126 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * Created by PhpStorm.
 | 
						|
 * User: Jenner
 | 
						|
 * Date: 2015/8/21
 | 
						|
 * Time: 14:30
 | 
						|
 */
 | 
						|
 | 
						|
namespace Jenner\SimpleFork\Lock;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * file lock
 | 
						|
 *
 | 
						|
 * @package Jenner\SimpleFork\Lock
 | 
						|
 */
 | 
						|
class FileLock implements LockInterface
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var string lock file
 | 
						|
     */
 | 
						|
    protected $file;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var resource
 | 
						|
     */
 | 
						|
    protected $fp;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var bool
 | 
						|
     */
 | 
						|
    protected $locked = false;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param $file
 | 
						|
     */
 | 
						|
    private function __construct($file)
 | 
						|
    {
 | 
						|
        if (!file_exists($file) || !is_readable($file)) {
 | 
						|
            throw new \RuntimeException("{$file} is not exists or not readable");
 | 
						|
        }
 | 
						|
        $this->fp = fopen($file, "r+");
 | 
						|
        if (!is_resource($this->fp)) {
 | 
						|
            throw new \RuntimeException("open {$file} failed");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * create a file lock instance
 | 
						|
     * if the file is not exists, it will be created
 | 
						|
     *
 | 
						|
     * @param string $file lock file
 | 
						|
     * @return FileLock
 | 
						|
     */
 | 
						|
    public static function create($file)
 | 
						|
    {
 | 
						|
        return new FileLock($file);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * get a lock
 | 
						|
     *
 | 
						|
     * @param bool $blocking
 | 
						|
     * @return mixed
 | 
						|
     */
 | 
						|
    public function acquire($blocking = true)
 | 
						|
    {
 | 
						|
        if ($this->locked) {
 | 
						|
            throw new \RuntimeException('already lock by yourself');
 | 
						|
        }
 | 
						|
 | 
						|
        if ($blocking) {
 | 
						|
            $locked = flock($this->fp, LOCK_EX);
 | 
						|
        } else {
 | 
						|
            $locked = flock($this->fp, LOCK_EX | LOCK_NB);
 | 
						|
        }
 | 
						|
 | 
						|
        if ($locked !== true) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        $this->locked = true;
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * is locked
 | 
						|
     *
 | 
						|
     * @return mixed
 | 
						|
     */
 | 
						|
    public function isLocked()
 | 
						|
    {
 | 
						|
        return $this->locked === true ? true : false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     *
 | 
						|
     */
 | 
						|
    public function __destory()
 | 
						|
    {
 | 
						|
        if ($this->locked) {
 | 
						|
            $this->release();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * release lock
 | 
						|
     *
 | 
						|
     * @return mixed
 | 
						|
     */
 | 
						|
    public function release()
 | 
						|
    {
 | 
						|
        if (!$this->locked) {
 | 
						|
            throw new \RuntimeException('release a non lock');
 | 
						|
        }
 | 
						|
 | 
						|
        $unlock = flock($this->fp, LOCK_UN);
 | 
						|
        fclose($this->fp);
 | 
						|
        if ($unlock !== true) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        $this->locked = false;
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
} |