aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/lock
diff options
context:
space:
mode:
authorAndreas Fischer <bantu@phpbb.com>2012-12-04 20:26:43 +0100
committerAndreas Fischer <bantu@phpbb.com>2012-12-04 20:26:43 +0100
commit2fdd039e5223b7acea3795811326945bd649bf49 (patch)
treeb0efba74b1bdc2eaad2443d7e65f61c66ee66a1e /phpBB/includes/lock
parentd7a23df2d9c3a9f93d8477e164edef0d263d8dcb (diff)
parent3e093c282a63df4d16b212859fd8137fd2bbca81 (diff)
downloadforums-2fdd039e5223b7acea3795811326945bd649bf49.tar
forums-2fdd039e5223b7acea3795811326945bd649bf49.tar.gz
forums-2fdd039e5223b7acea3795811326945bd649bf49.tar.bz2
forums-2fdd039e5223b7acea3795811326945bd649bf49.tar.xz
forums-2fdd039e5223b7acea3795811326945bd649bf49.zip
Merge remote-tracking branch 'p/ticket/10103' into develop
* p/ticket/10103: [ticket/10103] New and improved wording. [ticket/10103] Assert with messages. [ticket/10103] assertLessThan/assertGreaterThan. [ticket/10103] Inline assignment is bad? [ticket/10103] $rv had too few characters. [ticket/10103] Correct flock class documentation. [ticket/10103] Try a longer sleep for travis. [ticket/10103] Convert the rest of the tree to flock class. [ticket/10103] Test for flock lock class, with concurrency no less. [ticket/10103] Use flock lock class in messenger. [ticket/10103] Factor out flock lock class.
Diffstat (limited to 'phpBB/includes/lock')
-rw-r--r--phpBB/includes/lock/flock.php133
1 files changed, 133 insertions, 0 deletions
diff --git a/phpBB/includes/lock/flock.php b/phpBB/includes/lock/flock.php
new file mode 100644
index 0000000000..5c2288ce1b
--- /dev/null
+++ b/phpBB/includes/lock/flock.php
@@ -0,0 +1,133 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* File locking class
+* @package phpBB3
+*/
+class phpbb_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->locked)
+ {
+ 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;
+ }
+
+ /**
+ * 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;
+ }
+ }
+}