Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
75.00% covered (warning)
75.00%
3 / 4
CRAP
83.33% covered (warning)
83.33%
20 / 24
flock
0.00% covered (danger)
0.00%
0 / 1
75.00% covered (warning)
75.00%
3 / 4
11.56
83.33% covered (warning)
83.33%
20 / 24
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 acquire
0.00% covered (danger)
0.00%
0 / 1
7.93
73.33% covered (warning)
73.33%
11 / 15
 owns_lock
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 release
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\lock;
/**
* File locking class
*/
class flock
{
    /**
    * Path to the file to which access is controlled
    *
    * @var string
    */
    private $path;
    /**
    * File pointer for the lock file
    * @var string
    */
    private $lock_fp;
    /**
    * Constructor.
    *
    * You have to call acquire() to actually acquire the lock.
    *
    * @param    string    $path    Path to the file to which access is controlled
    */
    public function __construct($path)
    {
        $this->path = $path;
        $this->lock_fp = null;
    }
    /**
    * Tries to acquire the lock.
    *
    * If the lock is already held by another process, this call will block
    * until the other process releases the lock. If a lock is acquired and
    * is not released before script finishes but the process continues to
    * live (apache/fastcgi) then subsequent processes trying to acquire
    * the same lock will be blocked forever.
    *
    * If the lock is already held by the same process via another instance
    * of this class, this call will block forever.
    *
    * If flock function is disabled in php or fails to work, lock
    * acquisition will fail and false will be returned.
    *
    * @return    bool            true if lock was acquired
    *                            false otherwise
    */
    public function acquire()
    {
        if ($this->lock_fp)
        {
            return false;
        }
        // For systems that can't have two processes opening
        // one file for writing simultaneously
        if (file_exists($this->path . '.lock'))
        {
            $mode = 'rb+';
        }
        else
        {
            $mode = 'wb';
        }
        $this->lock_fp = @fopen($this->path . '.lock', $mode);
        if ($mode == 'wb')
        {
            if (!$this->lock_fp)
            {
                // Two processes may attempt to create lock file at the same time.
                // Have the losing process try opening the lock file again for reading
                // on the assumption that the winning process created it
                $mode = 'rb+';
                $this->lock_fp = @fopen($this->path . '.lock', $mode);
            }
            else
            {
                // Only need to set mode when the lock file is written
                @chmod($this->path . '.lock', 0666);
            }
        }
        if ($this->lock_fp)
        {
            if (!@flock($this->lock_fp, LOCK_EX))
            {
                throw new \phpbb\exception\http_exception(500, 'Failure while aqcuiring locks.');
            }
        }
        return (bool) $this->lock_fp;
    }
    /**
    * Does this process own the lock?
    *
    * @return    bool            true if lock is owned
    *                            false otherwise
    */
    public function owns_lock()
    {
        return (bool) $this->lock_fp;
    }
    /**
    * Releases the lock.
    *
    * The lock must have been previously obtained, that is, acquire() call
    * was issued and returned true.
    *
    * Note: Attempting to release a lock that is already released,
    * that is, calling release() multiple times, is harmless.
    *
    * @return null
    */
    public function release()
    {
        if ($this->lock_fp)
        {
            @flock($this->lock_fp, LOCK_UN);
            fclose($this->lock_fp);
            $this->lock_fp = null;
        }
    }
}