TYPO3 CMS  TYPO3_8-7
SemaphoreLockStrategy.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Locking;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
25 {
26  const FILE_LOCK_FOLDER = 'typo3temp/var/locks/';
27 
31  protected $id;
32 
36  protected $resource;
37 
41  protected $filePath = '';
42 
46  protected $isAcquired = false;
47 
52  public function __construct($subject)
53  {
54  $path = PATH_site . self::FILE_LOCK_FOLDER;
55  if (!is_dir($path)) {
56  // Not using mkdir_deep on purpose here, if typo3temp/var itself
57  // does not exist, this issue should be solved on a different
58  // level of the application.
59  if (!GeneralUtility::mkdir($path)) {
60  throw new LockCreateException('Cannot create directory ' . $path, 1460976250);
61  }
62  }
63  if (!is_writable($path)) {
64  throw new LockCreateException('Cannot write to directory ' . $path, 1460976320);
65  }
66  $this->filePath = $path . 'sem_' . md5((string)$subject);
67  touch($this->filePath);
68  $this->id = ftok($this->filePath, 'A');
69  if ($this->id === false) {
70  throw new LockCreateException('Cannot create key for semaphore using path ' . $this->filePath, 1396278734);
71  }
72  }
73 
77  public function __destruct()
78  {
79  $this->release();
80  // We do not call sem_remove() since this would remove the resource for other processes,
81  // we leave that to the system. This is not clean, but there's no other way to determine when
82  // a semaphore is no longer needed as a website is generally running endlessly
83  // and we have no way to detect if there is a process currently waiting on that lock
84  // or if the server is shutdown
85  }
86 
92  public function release()
93  {
94  if (!$this->isAcquired) {
95  return true;
96  }
97  $this->isAcquired = false;
98  return (bool)@sem_release($this->resource);
99  }
100 
106  public function isAcquired()
107  {
108  return $this->isAcquired;
109  }
110 
114  public static function getCapabilities()
115  {
116  if (function_exists('sem_get')) {
117  return self::LOCK_CAPABILITY_EXCLUSIVE;
118  }
119  return 0;
120  }
121 
129  public function acquire($mode = self::LOCK_CAPABILITY_EXCLUSIVE)
130  {
131  if ($this->isAcquired) {
132  return true;
133  }
134 
135  $this->resource = sem_get($this->id, 1);
136  if ($this->resource === false) {
137  throw new LockAcquireException('Unable to get semaphore with id ' . $this->id, 1313828196);
138  }
139 
140  $this->isAcquired = (bool)sem_acquire($this->resource);
141  return $this->isAcquired;
142  }
143 
147  public static function getPriority()
148  {
149  return 25;
150  }
151 
155  public function destroy()
156  {
157  if ($this->resource) {
158  sem_remove($this->resource);
159  @unlink($this->filePath);
160  }
161  }
162 }
acquire($mode=self::LOCK_CAPABILITY_EXCLUSIVE)