123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <?php
- namespace yii\mutex;
- use Yii;
- use yii\base\InvalidConfigException;
- use yii\helpers\FileHelper;
- class FileMutex extends Mutex
- {
- use RetryAcquireTrait;
-
- public $mutexPath = '@runtime/mutex';
-
- public $fileMode;
-
- public $dirMode = 0775;
-
- public $isWindows;
-
- private $_files = [];
-
- public function init()
- {
- parent::init();
- $this->mutexPath = Yii::getAlias($this->mutexPath);
- if (!is_dir($this->mutexPath)) {
- FileHelper::createDirectory($this->mutexPath, $this->dirMode, true);
- }
- if ($this->isWindows === null) {
- $this->isWindows = DIRECTORY_SEPARATOR === '\\';
- }
- }
-
- protected function acquireLock($name, $timeout = 0)
- {
- $filePath = $this->getLockFilePath($name);
- return $this->retryAcquire($timeout, function () use ($filePath, $name) {
- $file = fopen($filePath, 'w+');
- if ($file === false) {
- return false;
- }
- if ($this->fileMode !== null) {
- @chmod($filePath, $this->fileMode);
- }
- if (!flock($file, LOCK_EX | LOCK_NB)) {
- fclose($file);
- return false;
- }
-
-
-
-
-
-
-
-
-
-
- if (DIRECTORY_SEPARATOR !== '\\' && fstat($file)['ino'] !== @fileinode($filePath)) {
- clearstatcache(true, $filePath);
- flock($file, LOCK_UN);
- fclose($file);
- return false;
- }
- $this->_files[$name] = $file;
- return true;
- });
- }
-
- protected function releaseLock($name)
- {
- if (!isset($this->_files[$name])) {
- return false;
- }
- if ($this->isWindows) {
-
-
- flock($this->_files[$name], LOCK_UN);
- fclose($this->_files[$name]);
- @unlink($this->getLockFilePath($name));
- } else {
-
-
- unlink($this->getLockFilePath($name));
- flock($this->_files[$name], LOCK_UN);
- fclose($this->_files[$name]);
- }
- unset($this->_files[$name]);
- return true;
- }
-
- protected function getLockFilePath($name)
- {
- return $this->mutexPath . DIRECTORY_SEPARATOR . md5($name) . '.lock';
- }
- }
|