123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <?php
- /**
- * Created by PhpStorm.
- * User: Jenner
- * Date: 2015/8/12
- * Time: 20:52
- */
- namespace Jenner\SimpleFork\Lock;
- /**
- * sem lock
- *
- * @package Jenner\SimpleFork\Lock
- */
- class Semaphore implements LockInterface
- {
- /**
- * @var
- */
- private $lock_id;
- /**
- * @var bool
- */
- private $locked = false;
- /**
- * init a lock
- *
- * @param $key
- * @param $count
- * @throws \RuntimeException
- */
- private function __construct($key, $count = 1)
- {
- if (($this->lock_id = sem_get($this->_stringToSemKey($key), $count)) === false) {
- throw new \RuntimeException("Cannot create semaphore for key: {$key}");
- }
- }
- /**
- * Semaphore requires a numeric value as the key
- *
- * @param $identifier
- * @return int
- */
- protected function _stringToSemKey($identifier)
- {
- $md5 = md5($identifier);
- $key = 0;
- for ($i = 0; $i < 32; $i++) {
- $key += ord($md5{$i}) * $i;
- }
- return $key;
- }
- /**
- * create a lock instance
- *
- * @param $key
- * @return Semaphore
- */
- public static function create($key)
- {
- return new Semaphore($key);
- }
- /**
- * release lock
- *
- * @throws \RuntimeException
- */
- public function __destruct()
- {
- if ($this->isLocked()) {
- $this->release();
- }
- }
- /**
- * is locked
- *
- * @return bool
- */
- public function isLocked()
- {
- return $this->locked === true ? true : false;
- }
- /**
- * release lock
- *
- * @return bool
- * @throws \RuntimeException
- */
- public function release()
- {
- if (!$this->locked) {
- throw new \RuntimeException("release a non lock");
- }
- if (!sem_release($this->lock_id)) {
- return false;
- }
- $this->locked = false;
- return true;
- }
- /**
- * get a lock
- *
- * @param bool $blocking
- * @return bool
- */
- public function acquire($blocking = true)
- {
- if ($this->locked) {
- throw new \RuntimeException('already lock by yourself');
- }
- if ($blocking === false) {
- if (version_compare(PHP_VERSION, '5.6.0') < 0) {
- throw new \RuntimeException('php version is at least 5.6.0 for param blocking');
- }
- if (!sem_acquire($this->lock_id, true)) {
- return false;
- }
- $this->locked = true;
- return true;
- }
- if (!sem_acquire($this->lock_id)) {
- return false;
- }
- $this->locked = true;
- return true;
- }
- /**
- * remove the semaphore resource
- *
- * @return bool
- */
- public function remove()
- {
- if ($this->locked) {
- throw new \RuntimeException('can not remove a locked semaphore resource');
- }
- if (!is_resource($this->lock_id)) {
- throw new \RuntimeException('can not remove a empty semaphore resource');
- }
- if (!sem_release($this->lock_id)) {
- return false;
- }
- return true;
- }
- }
|