Browse Source

Merge pull request #15482 from ndm2/3.x-fix-fix-text-file-busy-errors

3.x - Fix `Text file busy` errors when deleting directories.
Mark Story 4 years ago
parent
commit
9908306366
2 changed files with 34 additions and 0 deletions
  1. 13 0
      src/Cache/Engine/FileEngine.php
  2. 21 0
      src/Filesystem/Folder.php

+ 13 - 0
src/Cache/Engine/FileEngine.php

@@ -280,11 +280,13 @@ class FileEngine extends CacheEngine
         /** @var \SplFileInfo $fileInfo */
         foreach ($contents as $fileInfo) {
             if ($fileInfo->isFile()) {
+                unset($fileInfo);
                 continue;
             }
 
             $realPath = $fileInfo->getRealPath();
             if (!$realPath) {
+                unset($fileInfo);
                 continue;
             }
 
@@ -293,8 +295,15 @@ class FileEngine extends CacheEngine
                 $this->_clearDirectory($path, $now, $threshold);
                 $cleared[] = $path;
             }
+
+            // possible inner iterators need to be unset too in order for locks on parents to be released
+            unset($fileInfo);
         }
 
+        // unsetting iterators helps releasing possible locks in certain environments,
+        // which could otherwise make `rmdir()` fail
+        unset($directory, $contents);
+
         return true;
     }
 
@@ -521,6 +530,10 @@ class FileEngine extends CacheEngine
             @unlink($path);
         }
 
+        // unsetting iterators helps releasing possible locks in certain environments,
+        // which could otherwise make `rmdir()` fail
+        unset($directoryIterator, $contents, $filtered);
+
         return true;
     }
 }

+ 21 - 0
src/Filesystem/Folder.php

@@ -582,6 +582,8 @@ class Folder
             $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_SELF);
             $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
         } catch (Exception $e) {
+            unset($directory, $iterator);
+
             if ($type === null) {
                 return [[], []];
             }
@@ -597,12 +599,14 @@ class Folder
             if ($skipHidden) {
                 $subPathName = $fsIterator->getSubPathname();
                 if ($subPathName[0] === '.' || strpos($subPathName, DIRECTORY_SEPARATOR . '.') !== false) {
+                    unset($fsIterator);
                     continue;
                 }
             }
             /** @var \FilesystemIterator $item */
             $item = $fsIterator->current();
             if (!empty($exceptions) && isset($exceptions[$item->getFilename()])) {
+                unset($fsIterator, $item);
                 continue;
             }
 
@@ -611,7 +615,15 @@ class Folder
             } elseif ($item->isDir() && !$item->isDot()) {
                 $directories[] = $itemPath;
             }
+
+            // inner iterators need to be unset too in order for locks on parents to be released
+            unset($fsIterator, $item);
         }
+
+        // unsetting iterators helps releasing possible locks in certain environments,
+        // which could otherwise make `rmdir()` fail
+        unset($directory, $iterator);
+
         if ($type === null) {
             return [$directories, $files];
         }
@@ -731,6 +743,8 @@ class Folder
                 $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::CURRENT_AS_SELF);
                 $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::CHILD_FIRST);
             } catch (Exception $e) {
+                unset($directory, $iterator);
+
                 return false;
             }
 
@@ -752,11 +766,18 @@ class Folder
                     } else {
                         $this->_errors[] = sprintf('%s NOT removed', $filePath);
 
+                        // inner iterators need to be unset too in order for locks on parents to be released
+                        unset($directory, $iterator, $item);
+
                         return false;
                     }
                 }
             }
 
+            // unsetting iterators helps releasing possible locks in certain environments,
+            // which could otherwise make `rmdir()` fail
+            unset($directory, $iterator);
+
             $path = rtrim($path, DIRECTORY_SEPARATOR);
             //@codingStandardsIgnoreStart
             if (@rmdir($path)) {