Fix AtomicWriter race condition on Windows
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 30 Sep 2014 01:00:51 +0000 (03:00 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 30 Sep 2014 01:01:47 +0000 (03:01 +0200)
wcfsetup/install/files/lib/system/io/AtomicWriter.class.php

index 9fecdac71965e911c83940544c353ea008a93831..66a83bae4f223ffa276e62d6c7c8cf43e6ee15ca 100644 (file)
@@ -49,7 +49,7 @@ class AtomicWriter extends File {
                        }
                        catch (SystemException $e) {
                                // allow at most 5 failures
-                               if (++$i == 5) {
+                               if (++$i === 5) {
                                        throw $e;
                                }
                        }
@@ -90,7 +90,21 @@ class AtomicWriter extends File {
                flock($this->resource, LOCK_UN);
                fclose($this->resource);
                
-               rename($this->filename, $this->targetFilename);
+               $i = 0;
+               while (true) {
+                       try {
+                               rename($this->filename, $this->targetFilename);
+                               break;
+                       }
+                       catch (SystemException $e) {
+                               // rename may fail on Windows with a high number
+                               // of concurrent requests
+                               // retry up to 5 times with a random sleep
+                               if (++$i === 5) throw $e;
+                               
+                               usleep(mt_rand(0, .1e6)); // 0 to .1 seconds
+                       }
+               }
        }
        
        /**