filePath = $path . 'sem_' . md5((string)$subject); touch($this->filePath); $this->id = ftok($this->filePath, 'A'); if ($this->id === -1) { throw new LockCreateException('Cannot create key for semaphore using path ' . $this->filePath, 1396278734); } } /** * Destructor */ public function __destruct() { $this->release(); // We do not call sem_remove() since this would remove the resource for other processes, // we leave that to the system. This is not clean, but there's no other way to determine when // a semaphore is no longer needed as a website is generally running endlessly // and we have no way to detect if there is a process currently waiting on that lock // or if the server is shutdown } /** * Release the lock * * @return bool Returns TRUE on success or FALSE on failure */ public function release() { if (!$this->isAcquired) { return true; } $this->isAcquired = false; return (bool)@sem_release($this->resource); } /** * Get status of this lock * * @return bool Returns TRUE if lock is acquired by this locker, FALSE otherwise */ public function isAcquired() { return $this->isAcquired; } /** * @return int LOCK_CAPABILITY_* elements combined with bit-wise OR */ public static function getCapabilities() { if (function_exists('sem_get')) { return self::LOCK_CAPABILITY_EXCLUSIVE; } return 0; } /** * Try to acquire a lock * * @param int $mode LOCK_CAPABILITY_EXCLUSIVE * @return bool Returns TRUE if the lock was acquired successfully * @throws LockAcquireException if a semaphore could not be retrieved */ public function acquire($mode = self::LOCK_CAPABILITY_EXCLUSIVE) { if ($this->isAcquired) { return true; } $resource = sem_get($this->id, 1); if ($resource === false) { throw new LockAcquireException('Unable to get semaphore with id ' . $this->id, 1313828196); } $this->resource = $resource; $this->isAcquired = (bool)sem_acquire($this->resource); return $this->isAcquired; } /** * @return int Returns a priority for the method. 0 to 100, 100 is highest */ public static function getPriority() { return $GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][self::class]['priority'] ?? self::DEFAULT_PRIORITY; } /** * Destroys the resource associated with the lock */ public function destroy() { if ($this->resource) { sem_remove($this->resource); @unlink($this->filePath); } } }