Index: kernel/classes/clusterfilehandlers/ezdbfilehandler.php
===================================================================
--- kernel/classes/clusterfilehandlers/ezdbfilehandler.php	(revision 17644)
+++ kernel/classes/clusterfilehandlers/ezdbfilehandler.php	(working copy)
@@ -74,16 +74,25 @@
                 return;
             }
         }
+
         $backendClassName = $GLOBALS['eZDBFileHandler_chosen_backend_class'];
         $this->backend = new $backendClassName;
-
         $this->backend->_connect();
+        $this->metaData['name'] = $filePath;
 
+        $this->loadMetaData();
+    }
+
+    /*!
+     \public
+     Load file meta information.
+    */
+    function loadMetaData()
+    {
         // Fetch metadata.
-        $this->metaData['name'] = $filePath;
-        if ( $filePath !== false )
+        if ( $this->metaData['name'] !== false )
         {
-            $metaData = $this->backend->_fetchMetadata( $filePath );
+            $metaData = $this->backend->_fetchMetadata( $this->metaData['name'] );
             if ( $metaData )
                 $this->metaData = $metaData;
         }
Index: kernel/classes/clusterfilehandlers/ezfsfilehandler.php
===================================================================
--- kernel/classes/clusterfilehandlers/ezfsfilehandler.php	(revision 17644)
+++ kernel/classes/clusterfilehandlers/ezfsfilehandler.php	(working copy)
@@ -43,9 +43,20 @@
     function eZFSFileHandler( $filePath = false )
     {
         eZDebugSetting::writeDebug( 'kernel-clustering', "fs::ctor( '$filePath' )" );
-        if ( $filePath !== false )
+        $this->metaData['name'] = $filePath;
+        $this->loadMetaData();
+    }
+
+    /*!
+     \public
+     Load file meta information.
+    */
+    function loadMetaData()
+    {
+        if ( $this->metaData['name'] !== false )
         {
             // fill $this->metaData
+            $filePath = $this->metaData['name'];
             eZDebug::accumulatorStart( 'dbfile', false, 'dbfile' );
             $this->metaData = @stat( $filePath );
             eZDebug::accumulatorStop( 'dbfile' );
@@ -139,20 +150,9 @@
 
         eZDebug::accumulatorStart( 'dbfile', false, 'dbfile' );
 
-        if ( !( $fh = fopen( $filePath, 'w' ) ) )
-        {
-            eZDebug::writeError( "Cannot open file '$filePath'", 'ezfsfilehandler::storeContents()' );
-            return false;
-        }
+        include_once( 'lib/ezfile/classes/ezfile.php' );
+        eZFile::create( basename( $filePath ), dirname( $filePath ), $contents );
 
-        if ( fwrite( $fh, $contents ) === false )
-        {
-            eZDebug::writeError( "Cannot write to '$filePath'", 'ezfsfilehandler::storeContents()' );
-            return false;
-        }
-
-        fclose( $fh );
-
         eZDebug::accumulatorStop( 'dbfile' );
     }
 
Index: lib/eztemplate/classes/eztemplatecachefunction.php
===================================================================
--- lib/eztemplate/classes/eztemplatecachefunction.php	(revision 17644)
+++ lib/eztemplate/classes/eztemplatecachefunction.php	(working copy)
@@ -35,6 +35,8 @@
 
 */
 
+define( 'eZTemplateCacheFunction_FileGenerateTimeout', 5 );
+
 class eZTemplateCacheFunction
 {
     /*!
@@ -234,6 +236,44 @@
                                                                "}\n" .
                                                                "else\n" .
                                                                "{" );
+
+        // Check if cache gen file exists, and wait
+        // for eZTemplateFunction_FileGenerateTimeout seconds if it does.
+        $code =
+            "\$phpPathGen = $filepathText . '.gen';\n" .
+            "\$cacheGenFile = eZClusterFileHandler::instance( \$phpPathGen );\n" .
+            "while( \$cacheGenFile->exists() &&\n" .
+            "\$cacheGenFile->mtime() + " . eZTemplateCacheFunction_FileGenerateTimeout . " < mktime() )\n" .
+            "{\n" .
+            "sleep( 1 );\n" .
+            "\$cacheGenFile->loadMetaData();\n" .
+            "}\n";
+        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code, array( 'spacing' => 0 ) );
+
+
+        // Cache file might have been generated by now.
+        $code = "\$cacheFile->loadMetaData();\n".
+            "if ( \$cacheFile->exists()";
+        if ( !$ignoreExpiry ) {
+            $code .= "\n    and \$cacheFile->mtime() >= ( time() - $expiryText )";
+        }
+        if ( !$ignoreContentExpiry ) {
+            $code .= "\n    and ( ( \$cacheFile->mtime() > \$globalExpiryTime ) or ( \$globalExpiryTime == -1 ) )";
+        }
+        $code .= " )\n" .
+                 "{\n" .
+                 "    \$contentData = \$cacheFile->size() ? \$cacheFile->fetchContents() : '';\n";
+        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code );
+        $newNodes[] = eZTemplateNodeTool::createWriteToOutputVariableNode( 'contentData', array( 'spacing' => 4 ) );
+        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "    unset( \$contentData );\n" .
+                                                               "}\n" .
+                                                               "else\n" .
+                                                               "{" );
+
+        // Create tmp cache file
+        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$cacheGenFile->storeContents( '1' );" );
+
+
         $newNodes[] = eZTemplateNodeTool::createOutputVariableIncreaseNode( array( 'spacing' => 4 ) );
         $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 );
         $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !isset( \$cacheStack ) )\n" .
@@ -259,7 +299,9 @@
         {
             $code .= "@unlink( $filepathText );\n";
         }
-        $code .= "rename( $filedirText. '/'. \$uniqid, $filepathText );\n";
+        $code .= "rename( $filedirText. '/'. \$uniqid, $filepathText );\n" .
+            "\$cacheGenFile->delete();\n" .
+            "unset( \$cacheGenFile );";
 
         // VS-DBFILE
 
@@ -271,7 +313,7 @@
         $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code, array( 'spacing' => 4 ) );
         $newNodes[] = eZTemplateNodeTool::createOutputVariableDecreaseNode( array( 'spacing' => 4 ) );
         $newNodes[] = eZTemplateNodeTool::createWriteToOutputVariableNode( 'cachedText', array( 'spacing' => 4 ) );
-        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "    unset( \$cachedText );\n}" );
+        $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "    unset( \$cachedText );\n}}" );
         return $newNodes;
     }
 
@@ -383,47 +425,68 @@
                         }
                     }
 
-                    // VS-DBFILE
-
                     // Check if we can restore
                     require_once( 'kernel/classes/ezclusterfilehandler.php' );
                     $cacheFile = eZClusterFileHandler::instance( $phpPath );
                     if ( $cacheFile->exists() && $cacheFile->mtime() >= $expiryTime )
                     {
                         $textElements[] = $cacheFile->fetchContents();
+                        return;
                     }
-                    else
+
+                    // Check if cache gen file exists, and wait
+                    // for eZTemplateFunction_FileGenerateTimeout seconds if it does.
+                    $phpPathGen = $phpPath . '.gen';
+                    $cacheGenFile = eZClusterFileHandler::instance( $phpPathGen );
+                    while( $cacheGenFile->exists() &&
+                           $cacheGenFile->mtime() + eZTemplateCacheFunction_FileGenerateTimeout < mktime() )
                     {
-                        // If no cache or expired cache, load data
-                        $children = $functionChildren;
+                        sleep( 1 );
+                        $cacheGenFile->loadMetaData();
+                    }
 
-                        $childTextElements = array();
-                        if ( is_array( $children ) )
+                    // Cache file might have been generated by now.
+                    $cacheFile->loadMetaData();
+                    if ( $cacheFile->exists() && $cacheFile->mtime() >= $expiryTime )
+                    {
+                        $textElements[] = $cacheFile->fetchContents();
+                        return;
+                    }
+
+                    $cacheGenFile->storeContents( '1' );
+
+                    // If no cache or expired cache, load data
+                    $children = $functionChildren;
+
+                    $childTextElements = array();
+                    if ( is_array( $children ) )
+                    {
+                        foreach ( array_keys( $children ) as $childKey )
                         {
-                            foreach ( array_keys( $children ) as $childKey )
-                            {
-                                $child =& $children[$childKey];
-                                $tpl->processNode( $child, $childTextElements, $rootNamespace, $currentNamespace );
-                            }
+                            $child =& $children[$childKey];
+                            $tpl->processNode( $child, $childTextElements, $rootNamespace, $currentNamespace );
                         }
-                        $text = implode( '', $childTextElements );
-                        $textElements[] = $text;
+                    }
+                    $text = implode( '', $childTextElements );
+                    $textElements[] = $text;
 
-                        include_once( 'lib/ezfile/classes/ezfile.php' );
-                        $ini =& eZINI::instance();
-                        $perm = octdec( $ini->variable( 'FileSettings', 'StorageDirPermissions' ) );
-                        $uniqid = md5( uniqid( 'ezpcache'. getmypid(), true ) );
-                        eZDir::mkdir( $phpDir, $perm, true );
-                        $fd = fopen( "$phpDir/$uniqid", 'w' );
-                        fwrite( $fd, $text );
-                        fclose( $fd );
-                        eZFile::rename( "$phpDir/$uniqid", $phpPath );
+                    include_once( 'lib/ezfile/classes/ezfile.php' );
+                    $ini =& eZINI::instance();
+                    $perm = octdec( $ini->variable( 'FileSettings', 'StorageDirPermissions' ) );
+                    $uniqid = md5( uniqid( 'ezpcache'. getmypid(), true ) );
+                    eZDir::mkdir( $phpDir, $perm, true );
+                    $fd = fopen( "$phpDir/$uniqid", 'w' );
+                    fwrite( $fd, $text );
+                    fclose( $fd );
+                    eZFile::rename( "$phpDir/$uniqid", $phpPath );
 
-                        // VS-DBFILE
-                        require_once( 'kernel/classes/ezclusterfilehandler.php' );
-                        $fileHandler = eZClusterFileHandler::instance();
-                        $fileHandler->fileStore( $phpPath, 'template-block', true );
-                    }
+                    // VS-DBFILE
+                    require_once( 'kernel/classes/ezclusterfilehandler.php' );
+                    $fileHandler = eZClusterFileHandler::instance();
+                    $fileHandler->fileStore( $phpPath, 'template-block', true );
+
+                    // Clean up "lock" file.
+                    $cacheGenFile->delete();
                 }
             } break;
         }
