Now I had the time to dig into this in detail.
modxcachemanager.class.php extends xpdocachemanager.
The set function in xpdo calls tje writeFile function, and here it is where it fails.
Added some log-code to xpdocachemanager.class.php:
public function writeFile($filename, $content, $mode= 'wb', $options= array()) {
$fh = fopen('/www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/debug_log.txt', 'a');
fwrite($fh, 'xpdocachemanager.class.php: Inside writeFile-function.'. ".\n");
$written= false;
if (!is_array($options)) {
$options = is_scalar($options) && !is_bool($options) ? array('new_folder_permissions' => $options) : array();
}
$dirname= dirname($filename);
if (!file_exists($dirname)) {
$this->writeTree($dirname, $options);
}
$mode = str_replace('+', '', $mode);
switch ($mode[0]) {
case 'a':
$append = true;
break;
default:
$append = false;
break;
}
$fmode = (strlen($mode) > 1 && in_array($mode[1], array('b', 't'))) ? "a{$mode[1]}" : 'a';
$file= @fopen($filename, $fmode);
if ($file) {
if ($append === true) {
fwrite($fh, 'xpdocachemanager.class.php: $append = true. $filename:' . $filename . ".\n");
$written= fwrite($file, $content);
} else {
fwrite($fh, 'xpdocachemanager.class.php: $append = false. $filename:' . $filename . ".\n");
$locked = false;
$attempt = 1;
$attempts = (integer) $this->getOption(xPDO::OPT_CACHE_ATTEMPTS, $options, 1);
fwrite($fh, 'xpdocachemanager.class.php: $attempts:' . $attempts . ". $filename: " . $filename . ".\n");
$attemptDelay = (integer) $this->getOption(xPDO::OPT_CACHE_ATTEMPT_DELAY, $options, 1000);
fwrite($fh, 'xpdocachemanager.class.php: $attemptDelay:' . $attemptDelay . ". $filename: " . $filename . ".\n");
while (!$locked && ($attempts === 0 || $attempt <= $attempts)) {
$locked = flock($file, LOCK_EX | LOCK_NB);
if ($locked == true) fwrite($fh, 'xpdocachemanager.class.php: Inside while loop. $locked = true. $filename:' . $filename . ".\n");
if ($locked == false) fwrite($fh, 'xpdocachemanager.class.php: Inside while loop. $locked = false. $filename:' . $filename . ".\n");
if (!$locked && $attemptDelay > 0 && ($attempts === 0 || $attempt < $attempts)) {
if ($locked == false) fwrite($fh, 'xpdocachemanager.class.php: usleep. $filename:' . $filename . ".\n");
usleep($attemptDelay);
}
$attempt++;
}
if ($locked) {
fwrite($fh, 'xpdocachemanager.class.php: $locked = true. $filename:' . $filename . ".\n");
fseek($file, 0);
ftruncate($file, 0);
$written= fwrite($file, $content);
if ($written == false) fwrite($fh, 'xpdocachemanager.class.php: $locked = true. $written = false. $filename:' . $filename . ".\n");
if ($written == true) fwrite($fh, 'xpdocachemanager.class.php: $locked = true. $written = true. $filename:' . $filename . ".\n");
flock($file, LOCK_UN);
}
}
@fclose($file);
}
if ($written == false) fwrite($fh, 'xpdocachemanager.class.php: $written = false. $filename:' . $filename . ".\n");
if ($written == true) fwrite($fh, 'xpdocachemanager.class.php: $written = true. $filename:' . $filename . ".\n");
fclose($fh);
return ($written !== false);
}
Example of output:
xpdocachemanager.class.php: Inside set-function..
xpdocachemanager.class.php: $fileName:./www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: Before writeFile-function..
xpdocachemanager.class.php: Inside writeFile-function..
xpdocachemanager.class.php: $append = false. $filename:/www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: $attempts:1. /www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php: /www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: $attemptDelay:1000. /www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php: /www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: Inside while loop. $locked = false. $filename:/www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: $locked = false. $filename:/www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
xpdocachemanager.class.php: $written = false. $filename:/www/webvol17/40/9cn1xungy6qci7w/test.boxma.se/public_html/core/cache/system_settings/config.cache.php.
Analyzing the output, it seems that MODx sets $append to false and goes into the while loop as it shold.
Here $locked should be set to true with '$locked = flock($file, LOCK_EX | LOCK_NB);'
But $locked is set to false.
Therefore the 'if ($locked)' clause does not trigger.
What I did as a work-around, was to add so the fwrite was triggered even at $locked = false:
if ($locked) {
fseek($file, 0);
ftruncate($file, 0);
$written= fwrite($file, $content);
flock($file, LOCK_UN);
} else {
$written= fwrite($file, $content);
}
Now. The question is if this is a bug in MODx, or a feature/bug in the flock-function as it seems that it returns a false value.
Or is it so, that flock is intended to return false and that the function needed to catch the false statement as well?
Shall i trigger this as a bug in MODx?
Regards
Sven