From 7e7639442fdb4b8e2ac107cc183b899597eb5633 Mon Sep 17 00:00:00 2001 From: Stephen Coakley Date: Thu, 3 Sep 2015 17:20:58 -0500 Subject: [PATCH] Keep track of PosixSemaphore size & handle cloning --- src/Sync/PosixSemaphore.php | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Sync/PosixSemaphore.php b/src/Sync/PosixSemaphore.php index d786724..1d42ca6 100644 --- a/src/Sync/PosixSemaphore.php +++ b/src/Sync/PosixSemaphore.php @@ -21,6 +21,11 @@ class PosixSemaphore implements SemaphoreInterface, \Serializable */ private $key; + /** + * @var int The number of total locks. + */ + private $maxLocks; + /** * @var resource A message queue of available locks. */ @@ -36,7 +41,12 @@ class PosixSemaphore implements SemaphoreInterface, \Serializable */ public function __construct($maxLocks, $permissions = 0600) { + if (!is_int($maxLocks) || $maxLocks < 0) { + throw new InvalidArgumentError('Max locks must be a non-negative integer.'); + } + $this->key = abs(crc32(spl_object_hash($this))); + $this->maxLocks = $maxLocks; $this->queue = msg_get_queue($this->key, $permissions); if (!$this->queue) { @@ -59,6 +69,16 @@ class PosixSemaphore implements SemaphoreInterface, \Serializable return !is_resource($this->queue) || !msg_queue_exists($this->key); } + /** + * Gets the maximum number of locks held by the semaphore. + * + * @return int The maximum number of locks held by the semaphore. + */ + public function getSize() + { + return $this->maxLocks; + } + /** * Gets the access permissions of the semaphore. * @@ -148,7 +168,7 @@ class PosixSemaphore implements SemaphoreInterface, \Serializable */ public function serialize() { - return serialize($this->key); + return serialize([$this->key, $this->maxLocks]); } /** @@ -159,13 +179,21 @@ class PosixSemaphore implements SemaphoreInterface, \Serializable public function unserialize($serialized) { // Get the semaphore key and attempt to re-connect to the semaphore in memory. - $this->key = unserialize($serialized); + list($this->key, $this->maxLocks) = unserialize($serialized); if (msg_queue_exists($this->key)) { $this->queue = msg_get_queue($this->key); } } + /** + * Clones the semaphore, creating a new semaphore with the same size and permissions. + */ + public function __clone() + { + $this->__construct($this->maxLocks, $this->getPermissions()); + } + /** * Releases a lock from the semaphore. *