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
|
<?php
|
||||||
namespace Icicle\Concurrent;
|
namespace Icicle\Concurrent;
|
||||||
|
|
||||||
|
use Icicle\Concurrent\Exception\SemaphoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A synchronous semaphore that uses System V IPC semaphores.
|
* 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 $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.
|
* 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.
|
* @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->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.');
|
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()
|
public function lock()
|
||||||
{
|
{
|
||||||
if (!sem_acquire($this->identifier)) {
|
if (!sem_acquire($this->handle)) {
|
||||||
throw new SemaphoreException('Failed to lock the semaphore.');
|
throw new SemaphoreException('Failed to lock the semaphore.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,7 +67,7 @@ class Semaphore
|
|||||||
*/
|
*/
|
||||||
public function unlock()
|
public function unlock()
|
||||||
{
|
{
|
||||||
if (!sem_release($this->identifier)) {
|
if (!sem_release($this->handle)) {
|
||||||
throw new SemaphoreException('Failed to unlock the semaphore.');
|
throw new SemaphoreException('Failed to unlock the semaphore.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,9 +75,9 @@ class Semaphore
|
|||||||
/**
|
/**
|
||||||
* Removes the semaphore if it still exists.
|
* 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();
|
$error = error_get_last();
|
||||||
|
|
||||||
if ($error['type'] !== E_WARNING) {
|
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