Acquire lock when flushing cache.

git-svn-id: http://svn.automattic.com/wordpress/trunk@3435 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2006-01-14 00:05:22 +00:00
parent f7ed2d60d3
commit 937e73d016

View File

@ -55,6 +55,7 @@ class WP_Object_Cache {
var $cache_enabled = false; var $cache_enabled = false;
var $expiration_time = 900; var $expiration_time = 900;
var $flock_filename = 'wp_object_cache.lock'; var $flock_filename = 'wp_object_cache.lock';
var $mutex;
var $cache = array (); var $cache = array ();
var $dirty_objects = array (); var $dirty_objects = array ();
var $non_existant_objects = array (); var $non_existant_objects = array ();
@ -64,6 +65,15 @@ class WP_Object_Cache {
var $warm_cache_hits = 0; var $warm_cache_hits = 0;
var $cache_misses = 0; var $cache_misses = 0;
function acquire_lock() {
// Acquire a write lock.
$this->mutex = @fopen($this->cache_dir.$this->flock_filename, 'w');
if ( false == $this->mutex)
return false;
flock($this->mutex, LOCK_EX);
return true;
}
function add($id, $data, $group = 'default', $expire = '') { function add($id, $data, $group = 'default', $expire = '') {
if (empty ($group)) if (empty ($group))
$group = 'default'; $group = 'default';
@ -89,12 +99,18 @@ class WP_Object_Cache {
function flush() { function flush() {
if ( !$this->cache_enabled ) if ( !$this->cache_enabled )
return; return true;
if ( ! $this->acquire_lock() )
return false;
$this->rm_cache_dir(); $this->rm_cache_dir();
$this->cache = array (); $this->cache = array ();
$this->dirty_objects = array (); $this->dirty_objects = array ();
$this->non_existant_objects = array (); $this->non_existant_objects = array ();
$this->release_lock();
return true; return true;
} }
@ -246,6 +262,12 @@ class WP_Object_Cache {
} }
} }
function release_lock() {
// Release write lock.
flock($this->mutex, LOCK_UN);
fclose($this->mutex);
}
function replace($id, $data, $group = 'default', $expire = '') { function replace($id, $data, $group = 'default', $expire = '') {
if (empty ($group)) if (empty ($group))
$group = 'default'; $group = 'default';
@ -274,10 +296,10 @@ class WP_Object_Cache {
//$this->stats(); //$this->stats();
if (!$this->cache_enabled) if (!$this->cache_enabled)
return; return true;
if (empty ($this->dirty_objects)) if (empty ($this->dirty_objects))
return; return true;
// Give the new dirs the same perms as wp-content. // Give the new dirs the same perms as wp-content.
$stat = stat(ABSPATH.'wp-content'); $stat = stat(ABSPATH.'wp-content');
@ -287,7 +309,7 @@ class WP_Object_Cache {
// Make the base cache dir. // Make the base cache dir.
if (!file_exists($this->cache_dir)) { if (!file_exists($this->cache_dir)) {
if (! @ mkdir($this->cache_dir)) if (! @ mkdir($this->cache_dir))
return; return false;
@ chmod($this->cache_dir, $dir_perms); @ chmod($this->cache_dir, $dir_perms);
} }
@ -296,13 +318,11 @@ class WP_Object_Cache {
@ chmod($this->cache_dir."index.php", $file_perms); @ chmod($this->cache_dir."index.php", $file_perms);
} }
// Acquire a write lock. if ( ! $this->acquire_lock() )
$mutex = @fopen($this->cache_dir.$this->flock_filename, 'w'); return false;
if ( false == $mutex)
return;
flock($mutex, LOCK_EX);
// Loop over dirty objects and save them. // Loop over dirty objects and save them.
$errors = 0;
foreach ($this->dirty_objects as $group => $ids) { foreach ($this->dirty_objects as $group => $ids) {
$group_dir = $this->make_group_dir($group, $dir_perms); $group_dir = $this->make_group_dir($group, $dir_perms);
@ -313,21 +333,24 @@ class WP_Object_Cache {
// Remove the cache file if the key is not set. // Remove the cache file if the key is not set.
if (!isset ($this->cache[$group][$id])) { if (!isset ($this->cache[$group][$id])) {
if (file_exists($cache_file)) if (file_exists($cache_file))
unlink($cache_file); @ unlink($cache_file);
continue; continue;
} }
$temp_file = tempnam($group_dir, 'tmp'); $temp_file = tempnam($group_dir, 'tmp');
$serial = CACHE_SERIAL_HEADER.serialize($this->cache[$group][$id]).CACHE_SERIAL_FOOTER; $serial = CACHE_SERIAL_HEADER.serialize($this->cache[$group][$id]).CACHE_SERIAL_FOOTER;
$fd = @fopen($temp_file, 'w'); $fd = @fopen($temp_file, 'w');
if ( false === $fd ) if ( false === $fd ) {
$errors++;
continue; continue;
}
fputs($fd, $serial); fputs($fd, $serial);
fclose($fd); fclose($fd);
if (!@ rename($temp_file, $cache_file)) { if (!@ rename($temp_file, $cache_file)) {
if (@ copy($temp_file, $cache_file)) { if (@ copy($temp_file, $cache_file))
@ unlink($temp_file); @ unlink($temp_file);
} else
$errors++;
} }
@ chmod($cache_file, $file_perms); @ chmod($cache_file, $file_perms);
} }
@ -335,9 +358,12 @@ class WP_Object_Cache {
$this->dirty_objects = array(); $this->dirty_objects = array();
// Release write lock. $this->release_lock();
flock($mutex, LOCK_UN);
fclose($mutex); if ( $errors )
return false;
return true;
} }
function stats() { function stats() {