|
From: Florin C B. <ory...@us...> - 2013-06-26 09:19:32
|
Update of /cvsroot/mxbb/core/includes/lock In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv25562/lock Added Files: db.php flock.php Log Message: --- NEW FILE: flock.php --- <?php /** * * @package MXP3 * @copyright (c) 2012 phpBB Group * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ /** * @ignore */ if (!defined('IN_PORTAL')) { exit; } /** * File locking class * @package MXP3 */ class mx_lock_flock { /** * Path to the file to which access is controlled * * @var string */ private $path; /** * File pointer for the lock file * @var string */ private $lock_fp; /** * Constructor. * * You have to call acquire() to actually acquire the lock. * * @param string $path Path to the file to which access is controlled */ public function __construct($path) { $this->path = $path; $this->lock_fp = null; } /** * Tries to acquire the lock. * * If the lock is already held by another process, this call will block * until the other process releases the lock. If a lock is acquired and * is not released before script finishes but the process continues to * live (apache/fastcgi) then subsequent processes trying to acquire * the same lock will be blocked forever. * * If the lock is already held by the same process via another instance * of this class, this call will block forever. * * If flock function is disabled in php or fails to work, lock * acquisition will fail and false will be returned. * * @return bool true if lock was acquired * false otherwise */ public function acquire() { if ($this->lock_fp) { return false; } // For systems that can't have two processes opening // one file for writing simultaneously if (file_exists($this->path . '.lock')) { $mode = 'rb'; } else { $mode = 'wb'; } $this->lock_fp = @fopen($this->path . '.lock', $mode); if ($mode == 'wb') { if (!$this->lock_fp) { // Two processes may attempt to create lock file at the same time. // Have the losing process try opening the lock file again for reading // on the assumption that the winning process created it $mode = 'rb'; $this->lock_fp = @fopen($this->path . '.lock', $mode); } else { // Only need to set mode when the lock file is written @chmod($this->path . '.lock', 0666); } } if ($this->lock_fp) { @flock($this->lock_fp, LOCK_EX); } return (bool) $this->lock_fp; } /** * Does this process own the lock? * * @return bool true if lock is owned * false otherwise */ public function owns_lock() { return (bool) $this->lock_fp; } /** * Releases the lock. * * The lock must have been previously obtained, that is, acquire() call * was issued and returned true. * * Note: Attempting to release a lock that is already released, * that is, calling release() multiple times, is harmless. * * @return null */ public function release() { if ($this->lock_fp) { @flock($this->lock_fp, LOCK_UN); fclose($this->lock_fp); $this->lock_fp = null; } } } --- NEW FILE: db.php --- <?php /** * * @package MXP3 * @copyright (c) 2010 phpBB Group * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ /** * @ignore */ if (!defined('IN_PORTAL')) { exit; } /** * Database locking class * @package MXP3 */ class mx_lock_db { /** * Name of the config variable this lock uses * @var string */ private $config_name; /** * Unique identifier for this lock. * * @var string */ private $unique_id; /** * Stores the state of this lock * @var bool */ private $locked; /** * The MXP configuration * @var phpbb_config */ private $portal_config; /** * A database connection * @var mx_db_driver */ private $db; /** * Creates a named released instance of the lock. * * You have to call acquire() to actually create the lock. * * @param string $config_name A config variable to be used for locking * @param array $config The phpBB configuration * @param phpbb_db_driver $db A database connection */ public function __construct($config_name, mx_config $portal_config, mx_db_driver $db) { $this->portal_config_name = $config_name; $this->portal_config = $portal_config; $this->db = $db; } /** * Tries to acquire the lock by updating * the configuration variable in the database. * * As a lock may only be held by one process at a time, lock * acquisition may fail if another process is holding the lock * or if another process obtained the lock but never released it. * Locks are forcibly released after a timeout of 1 hour. * * @return bool true if lock was acquired * false otherwise */ public function acquire() { if ($this->locked) { return false; } if (!isset($this->portal_config[$this->portal_config_name])) { $this->portal_config->set($this->portal_config_name, '0', false); } $lock_value = $this->portal_config[$this->portal_config_name]; // make sure lock cannot be acquired by multiple processes if ($lock_value) { // if the other process is running more than an hour already we have to assume it // aborted without cleaning the lock $time = explode(' ', $lock_value); $time = $time[0]; if ($time + 3600 >= time()) { return false; } } $this->unique_id = time() . ' ' . unique_id(); // try to update the config value, if it was already modified by another // process we failed to acquire the lock. $this->locked = $this->portal_config->set_atomic($this->portal_config_name, $lock_value, $this->unique_id, false); return $this->locked; } /** * Does this process own the lock? * * @return bool true if lock is owned * false otherwise */ public function owns_lock() { return (bool) $this->locked; } /** * Releases the lock. * * The lock must have been previously obtained, that is, acquire() call * was issued and returned true. * * Note: Attempting to release a lock that is already released, * that is, calling release() multiple times, is harmless. * * @return null */ public function release() { if ($this->locked) { $this->portal_config->set_atomic($this->portal_config_name, $this->unique_id, '0', false); $this->locked = false; } } } |