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:
parent
2c40e0ddcb
commit
8dd597238d
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user