1
0
mirror of https://github.com/danog/parallel.git synced 2024-11-26 20:34:40 +01:00

Semaphore handles can be serialized across contexts

This commit is contained in:
coderstephen 2015-07-10 16:17:18 -05:00
parent 2c40e0ddcb
commit 8dd597238d

View File

@ -1,33 +1,53 @@
<?php
namespace Icicle\Concurrent;
use Icicle\Concurrent\Exception\SemaphoreException;
/**
* A synchronous semaphore that uses System V IPC semaphores.
*/
class Semaphore
class Semaphore implements \Serializable
{
/**
* @var int The key to the semaphore.
*/
private $key;
private $identifier;
/**
* @var int The maximum number of locks.
*/
private $maxLocks;
/**
* @var resource An open handle to the semaphore.
*/
private $handle;
/**
* Creates a new semaphore.
*
* @param int $max The maximum number of processes that can lock the semaphore.
* @param int $maxLocks The maximum number of processes that can lock the semaphore.
* @param int $permissions Permissions to access the semaphore.
*/
public function __construct($max = 1, $permissions = 0666)
public function __construct($maxLocks = 1, $permissions = 0666)
{
$this->key = abs(crc32(spl_object_hash($this)));
$this->identifier = sem_get($this->key, $max, $permissions);
$this->maxLocks = $maxLocks;
$this->handle = sem_get($this->key, $maxLocks, $permissions, 0);
if ($this->identifier === false) {
if ($this->handle === false) {
throw new SemaphoreException('Failed to create the semaphore.');
}
}
public function __destruct()
/**
* Gets the maximum number of locks.
*
* @return int The maximum number of locks.
*/
public function getMaxLocks()
{
$this->remove();
return $this->maxLocks;
}
/**
@ -37,7 +57,7 @@ class Semaphore
*/
public function lock()
{
if (!sem_acquire($this->identifier)) {
if (!sem_acquire($this->handle)) {
throw new SemaphoreException('Failed to lock the semaphore.');
}
}
@ -47,7 +67,7 @@ class Semaphore
*/
public function unlock()
{
if (!sem_release($this->identifier)) {
if (!sem_release($this->handle)) {
throw new SemaphoreException('Failed to unlock the semaphore.');
}
}
@ -55,9 +75,9 @@ class Semaphore
/**
* Removes the semaphore if it still exists.
*/
public function remove()
public function destroy()
{
if (!@sem_remove($this->identifier)) {
if (!@sem_remove($this->handle)) {
$error = error_get_last();
if ($error['type'] !== E_WARNING) {
@ -65,4 +85,27 @@ class Semaphore
}
}
}
/**
* Serializes the semaphore.
*
* @return string The serialized semaphore.
*/
public function serialize()
{
return serialize([$this->key, $this->maxLocks]);
}
/**
* Unserializes a serialized semaphore.
*
* @param string $serialized The serialized semaphore.
*/
public function unserialize($serialized)
{
// Get the semaphore key and attempt to re-connect to the semaphore in
// memory.
list($this->key, $this->maxLocks) = unserialize($serialized);
$this->handle = sem_get($this->key, $maxLocks);
}
}