Login   Register  
PHP Classes
elePHPant
Icontem

File: docs/api/files/Mutex.php.txt

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of AlexanderC  >  Threadator  >  docs/api/files/Mutex.php.txt  >  Download  
File: docs/api/files/Mutex.php.txt
Role: Documentation
Content type: text/plain
Description: Documentation
Class: Threadator
Create threads and send messages between them
Author: By
Last change:
Date: 7 months ago
Size: 4,659 bytes
 

Contents

Class file image Download
<?php
/**
 * @author AlexanderC <self@alexanderc.me>
 * @date 4/7/14
 * @time 9:09 PM
 */

namespace Threadator;


/**
 * Semaphore based mutex implementation
 *
 * @package Threadator
 */
class Mutex implements IMutexType
{
    const USLEEP_WAIT = 300;

    /**
     * @var string
     */
    protected $identifier;

    /**
     * @var int
     */
    protected $type;

    /**
     * @var mixed
     */
    protected $identity;

    /**
     * @var int
     */
    protected $systemVIPCKey;

    /**
     * @var resource
     */
    protected $semaphore;

    /**
     * @var bool
     */
    protected $acquired = false;

    /**
     * @param mixed $identity
     * @param int $type
     * @throws \RuntimeException
     */
    public function __construct($identity, $type = self::IDX)
    {
        $this->identity = $identity;
        $this->type = $type;

        $this->generateIdentifier();
        $this->generateSystemVIPCKey();

        if(false === ($this->semaphore = @sem_get($this->systemVIPCKey/*, 1, 0666, 1*/))) {
            throw new \RuntimeException("Unable to get semaphore");
        }
    }

    /**
     * @return bool
     */
    public function waitAcquire()
    {
        while(!$this->acquire()) {
            usleep(self::USLEEP_WAIT);
        }

        $this->acquired = true;

        return true;
    }

    /**
     * @return bool
     */
    public function acquire()
    {
        $result = sem_acquire($this->semaphore);

        if(true === $result) {
            $this->acquired = true;
        }

        return $result;
    }

    /**
     * @return bool
     */
    public function release()
    {
        if(true === $this->acquired) {
            $result = sem_release($this->semaphore);

            if(true === $result) {
                $this->acquired = false;
            }

            return $result;
        }

        return true;
    }

    /**
     * @return string
     */
    public function getIdentifier()
    {
        return $this->identifier;
    }

    /**
     * @return mixed
     */
    public function getIdentity()
    {
        return $this->identity;
    }

    /**
     * @return int
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * @return int
     */
    public function getSystemVIPCKey()
    {
        return $this->systemVIPCKey;
    }

    /**
     * @throws \UnexpectedValueException
     */
    protected function generateIdentifier()
    {
        switch($this->type) {
            case self::T_IDX:
                $this->identifier = sprintf("_thdt_mutex_tidx:%s", (string) $this->identity);
                break;
            case self::T_FILE:
                $this->identifier = sprintf("_thdt_mutex_tfile:%s", (string) $this->identity);
                break;
            case self::T_FUNCTION:
                if($this->identity instanceof \Closure) { // case of lambda
                    $this->identifier = sprintf("_thdt_mutex_tfunction:%s", spl_object_hash($this->identity));
                } else {
                    $this->identifier = sprintf("_thdt_mutex_tfunction:%s", (string) $this->identity);
                }

                break;
            case self::T_METHOD:
                if(is_array($this->identity)) {
                    $class = is_object($this->identity[0]) ? get_class($this->identity[0]) : $this->identity[0];
                    $this->identifier = sprintf("_thdt_mutex_tmethod:%s::%s", $class, $this->identity[1]);
                } else {
                    $this->identifier = sprintf("_thdt_mutex_tmethod:%s", (string) $this->identity);
                }
                break;
            case self::T_CLASS:
                if(is_object($this->identity)) {
                    $this->identifier = sprintf("_thdt_mutex_tclass:%s", get_class($this->identity));
                } else {
                    $this->identifier = sprintf("_thdt_mutex_tclass:%s", (string) $this->identity);
                }
                break;
            case self::T_OBJECT:
                $this->identifier = sprintf("_thdt_mutex_tobject:%s", spl_object_hash($this->identity));
                break;

            default: throw new \UnexpectedValueException("Unknown Mutex type");
        }
    }

    /**
     * @return void
     */
    protected function generateSystemVIPCKey()
    {
        $identifierFile = sprintf("%s/%s", sys_get_temp_dir(), base64_encode($this->identifier));
        @touch($identifierFile);
        $this->systemVIPCKey = ftok($identifierFile, "m");
    }

    /**
     * @return void
     */
    public function __destruct()
    {
        $this->release();
    }
}