diff options
| author | Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de> | 2022-05-10 22:36:06 +0000 |
|---|---|---|
| committer | Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de> | 2022-05-10 22:36:06 +0000 |
| commit | c054faf90288a75fc3680480434ba93b7f5b287b (patch) | |
| tree | 0ced27539a1824ae6fd507899f84b67c12c6360d /lib/classes/FileLock.class.php | |
| parent | 021a1958f0d4a881396b37bb4cf436c8525b1d62 (diff) | |
rework locking and drop CRONJOBS_ESCALATION setting, fixes #771
Closes #771
Merge request studip/studip!592
Diffstat (limited to 'lib/classes/FileLock.class.php')
| -rw-r--r-- | lib/classes/FileLock.class.php | 80 |
1 files changed, 27 insertions, 53 deletions
diff --git a/lib/classes/FileLock.class.php b/lib/classes/FileLock.class.php index cf6c00a..064d41e 100644 --- a/lib/classes/FileLock.class.php +++ b/lib/classes/FileLock.class.php @@ -20,24 +20,7 @@ class FileLock { - protected static $directory = ''; - - /** - * Sets a new base path for the locks. - * - * @param String $directory - * @throws RuntimeException if provided directory is either not existant - * or is not a directory or is not writable. - */ - public static function setDirectory($directory) - { - if (!file_exists($directory) || !is_dir($directory) || !is_writable($directory)) { - throw new RuntimeException('Passed directory is not an actual directory or is not writable.'); - } - self::$directory = rtrim($directory, '/') . '/'; - } - - protected $filename; + protected $file; /** * Constructs a new lock object with the provided id. @@ -46,55 +29,46 @@ class FileLock */ public function __construct($id) { - $this->filename = self::$directory . '.' . $id . '.json'; - } - - /** - * Returns the filename of the lock. - * - * @return String Filename of the lock - */ - public function getFilename() - { - return $this->filename; + $this->file = fopen("{$GLOBALS['TMP_PATH']}/$id.json", 'c+'); + + if (!$this->file) { + throw new RuntimeException('failed to create lock file.'); + } } /** - * Establish or renew the current lock. Provided lock information will - * be stored with the lock. + * Try to aquire a file lock. The provided lock information will + * be stored with the lock. If the lock cannot be aquired, the + * lock information in $data is updated from the lock file. * - * @param Array $data Additional information to bestore with the lock + * @param array $data additional data to be stored with the lock + * @return boolean true on success or false on failure */ - public function lock($data = []) + public function tryLock(&$data = []) { - $data['timestamp'] = time(); - file_put_contents($this->filename, json_encode($data)); - } + rewind($this->file); + + if (flock($this->file, LOCK_EX | LOCK_NB)) { + ftruncate($this->file, 0); + fwrite($this->file, json_encode($data)); + fflush($this->file); + + return true; + } else { + $json = stream_get_contents($this->file); + $data = json_decode($json, true); - /** - * Tests whether the lock is in use. Returns lock information in - * $lock_data. - * - * @param mixed $lock_data Information stored in lock - * @return bool Indicates whether the lock is active or not - */ - public function isLocked(&$lock_data = null) - { - if (!file_exists($this->filename)) { return false; } - - $lock_data = json_decode(file_get_contents($this->filename), true); - return true; } /** * Releases a previously obtained lock + * + * @return boolean true on success or false on failure */ public function release() { - if (file_exists($this->filename)) { - unlink($this->filename); - } + return flock($this->file, LOCK_UN); } -}
\ No newline at end of file +} |
