aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/FileLock.class.php
diff options
context:
space:
mode:
authorElmar Ludwig <elmar.ludwig@uni-osnabrueck.de>2022-05-10 22:36:06 +0000
committerElmar Ludwig <elmar.ludwig@uni-osnabrueck.de>2022-05-10 22:36:06 +0000
commitc054faf90288a75fc3680480434ba93b7f5b287b (patch)
tree0ced27539a1824ae6fd507899f84b67c12c6360d /lib/classes/FileLock.class.php
parent021a1958f0d4a881396b37bb4cf436c8525b1d62 (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.php80
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
+}