fixed race condition when writing template cache on disk (closes #97)
authorFabien Potencier <fabien.potencier@gmail.com>
Thu, 12 Aug 2010 19:56:30 +0000 (21:56 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Thu, 12 Aug 2010 19:56:30 +0000 (21:56 +0200)
lib/Twig/Environment.php

index 5d58245..08b295c 100644 (file)
@@ -200,7 +200,7 @@ class Twig_Environment
                 if (!file_exists($cache) || ($this->isAutoReload() && !$this->loader->isFresh($name, filemtime($cache)))) {
                     $content = $this->compileSource($this->loader->getSource($name), $name);
 
-                    if (false === file_put_contents($cache, $content, LOCK_EX)) {
+                    if (false === $this->writeCacheFile($cache, $content)) {
                         eval('?>'.$content);
                     } else {
                         require_once $cache;
@@ -403,4 +403,19 @@ class Twig_Environment
 
         return $this->filters;
     }
+
+    protected function writeCacheFile($file, $content)
+    {
+        $tmpFile = tempnam(dirname($file), basename($file));
+        if (false !== @file_put_contents($tmpFile, $content)) {
+            // rename does not work on Win32 before 5.2.6
+            if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
+                chmod($file, 0644);
+
+                return;
+            }
+        }
+
+        throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file));
+    }
 }