<?php
namespace App\Cron\Mutex; class FLock implements AbstractLock { private $handle = null; private $file = null; public function __construct($id) { $CFG = \Engine\Loader_Cfg::getInstance()->getGlobal(); $this->setFile(sprintf("%s%s%s.lock", APP_REAL_PATH, $CFG['paths']['temporary'], $id)); } protected function setFile($file) { $this->file = $file; return $this; } public function lock() { if (!file_exists($this->file)) { file_put_contents($this->file, ''); chmod($this->file, 0777); } $this->handle = fopen($this->file, 'wb'); if ($this->handle) { flock($this->handle, LOCK_EX); } return $this; } public function unlock() { if ($this->handle) { flock($this->handle, LOCK_UN); fclose($this->handle); } return $this; } public function isLocked() { if (!file_exists($this->file)) { file_put_contents($this->file, ''); chmod($this->file, 0777); return false; } $handle = fopen($this->file, 'wb'); if ($handle) { $ret = !flock($handle, LOCK_EX | LOCK_NB); fclose($handle); return $ret; } return true; } public function isLockedWithTimeout($timeoutMin=0.0, $timeoutMax=0.5, $loopsMin=1, $loopsMax=PHP_INT_MAX) { $keepWaiting = true; $loopStart = microtime(true); $locked = true; $loops = 0; do { if ($keepWaiting && !$this->isLocked()) { $locked = false; } if ($timeoutMax!==null && $keepWaiting && (microtime(true) - $loopStart)>=$timeoutMax) { $keepWaiting = false; } if ($loopsMax!==null && $keepWaiting && $loops>=$loopsMax) { $keepWaiting = false; } if ($loopsMin!==null && !$keepWaiting && $loops<$loopsMin) { $keepWaiting = true; } if ($timeoutMin!==null && !$keepWaiting && (microtime(true) - $loopStart)<$timeoutMin) { $keepWaiting = true; } if ($keepWaiting && $locked) { usleep(1); } $loops++; } while ($keepWaiting && $locked); return $locked; } public function rawGetIsLockedReasons() { return []; } public function wasAquired() { return (bool)$this->handle; } public function lockWithTimeout($timeout) { $keepWaiting = true; $loopStart = microtime(true); $locked = false; do { if ($keepWaiting && !$this->isLocked()) { $keepWaiting = false; $locked = true; $this->lock(); } if ($keepWaiting && (microtime(true) - $loopStart)>=$timeout) { $keepWaiting = false; } if ($keepWaiting) { usleep(1); } } while ($keepWaiting); return $locked; } public function removeLock() { unlink($this->file); return $this; } } 