Bug #18279 » 0007630_v2.patch

Administrator Admin, 2008-02-25 18:28

View differences:

t3lib/class.t3lib_lock.php (Arbeitskopie)
62 62
class t3lib_lock {
63 63
	private $method;
64 64
	private $id;		// Identifier used for this lock
65
	private $resource;	// Resource used for this lock (can be a file or a semaphore resource) 
65 66
	private $filepointer;
66 67
	private $isAcquired = false;
67 68

  
......
94 95
		}
95 96

  
96 97
			// Detect locking method
97
		if (in_array($method, array('disable', 'simple','flock','semaphore'))) {
98
		if (in_array($method, array('disable', 'simple', 'flock', 'semaphore'))) {
98 99
			$this->method = $method;
99 100
		} else {
100 101
			throw new Exception('No such method "'.$method.'"');
......
105 106
			case 'simple':
106 107
			case 'flock':
107 108
				$path = PATH_site.'typo3temp/locks/';
108
				$this->id = $path.md5($id);
109
				if (!is_dir($path)) {
110
					t3lib_div::mkdir($path);
111
				}
112
				$this->id = md5($id);
113
				$this->resource = $path.$this->id;
109 114
				$success = true;
110 115
			break;
111 116
			case 'semaphore':
112
				$id = abs(crc32($id));
113
				if (($this->id = sem_get($id, 1))==true) {
117
				$this->id = abs(crc32($id));
118
				if (($this->resource = sem_get($this->id, 1))==true) {
114 119
					$success = true;
115 120
				}
116 121
			break;
......
135 140

  
136 141
		switch ($this->method) {
137 142
			case 'simple':
138
				if (is_file($this->id)) {
143
				if (is_file($this->resource)) {
144
					$this->sysLog('Waiting for a different process to release the lock');
139 145
					$i = 0;
140 146
					while ($i<$this->loops) {
141 147
						$i++;
142 148
						usleep($this->step*1000);
143 149
						clearstatcache();
144
						if (!is_file($this->id)) {	// Lock became free, leave the loop
150
						if (!is_file($this->resource)) {	// Lock became free, leave the loop
151
							$this->sysLog('Different process released the lock');
145 152
							$noWait = false;
146 153
							break;
147 154
						}
......
150 157
					$noWait = true;
151 158
				}
152 159

  
153
				if (($this->filepointer = touch($this->id)) == false) {
160
				if (($this->filepointer = touch($this->resource)) == false) {
154 161
					throw new Exception('Lock file could not be created');
155 162
				}
156 163
			break;
157 164
			case 'flock':
158
				if (($this->filepointer = fopen($this->id, 'w+')) == false) {
165
				if (($this->filepointer = fopen($this->resource, 'w+')) == false) {
159 166
					throw new Exception('Lock file could not be opened');
160 167
				}
161 168

  
......
164 171
				} elseif (flock($this->filepointer, LOCK_EX) == true) {		// Lock with blocking (waiting for similar locks to become released)
165 172
					$noWait = false;
166 173
				} else {
167
					throw new Exception('Could not lock file "'.$this->id.'"');
174
					throw new Exception('Could not lock file "'.$this->resource.'"');
168 175
				}
169 176
			break;
170 177
			case 'semaphore':
171
				if (sem_acquire($this->id)) {
178
				if (sem_acquire($this->resource)) {
172 179
						// Unfortunately it seems not possible to find out if the request was blocked, so we return false in any case to make sure the operation is tried again.
173 180
					$noWait = false;
174 181
				}
......
196 203
		$success = true;
197 204
		switch ($this->method) {
198 205
			case 'simple':
199
				if (unlink($this->id) == false) {
206
				if (unlink($this->resource) == false) {
200 207
					$success = false;
201 208
				}
202 209
			break;
......
205 212
					$success = false;
206 213
				}
207 214
				fclose($this->filepointer);
208
				unlink($this->id);
215
				unlink($this->resource);
209 216
			break;
210 217
			case 'semaphore':
211
				if (!sem_release($this->id)) {
218
				if (sem_release($this->resource)) {
219
					sem_remove($this->resource);
220
				} else {
212 221
					$success = false;
213 222
				}
214 223
			break;
......
231 240
	}
232 241

  
233 242
	/**
234
	 * Return the ID of which is currently used
243
	 * Return the ID which is currently used
235 244
	 *
236 245
	 * @return	string		Locking ID
237 246
	 */
......
240 249
	}
241 250

  
242 251
	/**
252
	 * Return the resource which is currently used.
253
	 * Depending on the locking method this can be a filename or a semaphore resource.
254
	 *
255
	 * @return	mixed		Locking resource (filename as string or semaphore as resource)
256
	 */
257
	public function getResource()	{
258
		return $this->resource;
259
	}
260

  
261
	/**
243 262
	 * Return the status of a lock
244 263
	 *
245 264
	 * @return	string		Returns true if lock is acquired, false otherwise
......
247 266
	public function getLockStatus()	{
248 267
		return $this->isAcquired;
249 268
	}
269

  
270
	/**
271
	 * Adds a common log entry for this locking API using t3lib_div::sysLog().
272
	 * Example: 25-02-08 17:58 - cms: Locking [simple::0aeafd2a67a6bb8b9543fb9ea25ecbe2]: Acquired
273
	 *
274
	 * @param	string		$message: The message to be logged
275
	 * @param	integer		$severity: Severity - 0 is info (default), 1 is notice, 2 is warning, 3 is error, 4 is fatal error
276
	 * @return	void
277
	 */
278
	public function sysLog($message, $severity=0) {
279
		t3lib_div::sysLog('Locking ['.$this->method.'::'.$this->id.']: '.trim($message), 'cms', $severity);
280
	}
250 281
}
251 282

  
252 283

  
typo3/sysext/cms/tslib/class.tslib_fe.php (Arbeitskopie)
2723 2723
	 * Lock the page generation process
2724 2724
	 * The lock is used to queue page requests until this page is successfully stored in the cache.
2725 2725
	 *
2726
	 * @param	object		Reference to a locking object
2726
	 * @param	t3lib_lock	Reference to a locking object
2727 2727
	 * @param	string		String to identify the lock in the system
2728 2728
	 * @return	boolean		Returns true if the lock could be obtained, false otherwise (= process had to wait for existing lock to be released)
2729 2729
	 * @see releasePageGenerationLock()
2730 2730
	 */
2731 2731
	function acquirePageGenerationLock(&$lockObj, $key)	{
2732 2732
		if ($this->no_cache || $this->headerNoCache()) {
2733
			$lockObj->sysLog('Page is not cached, no locking required');
2733 2734
			return true;	// No locking is needed if caching is disabled
2734 2735
		}
2735 2736

  
......
2744 2745
					// true = Page could get locked without blocking
2745 2746
					// false = Page could get locked but process was blocked before
2746 2747
				$success = $lockObj->acquire();
2748
				if ($lockObj->getLockStatus()) {
2749
					$lockObj->sysLog('Acquired lock');
2750
				}
2747 2751
			}
2748 2752
		} catch (Exception $e) {
2749
			t3lib_div::sysLog('Locking failed: '.$e->getMessage(), 'cms', 3);
2753
			$lockObj->sysLog('Failed to acquire lock: '.$e->getMessage(), 3);
2750 2754
			$success = false;	// If locking fails, return with false and continue without locking
2751 2755
		}
2752 2756

  
......
2756 2760
	/**
2757 2761
	 * Release the page generation lock
2758 2762
	 *
2759
	 * @param	object		Reference to a locking object
2763
	 * @param	t3lib_lock	Reference to a locking object
2760 2764
	 * @return	boolean		Returns true on success, false otherwise
2761 2765
	 * @see acquirePageGenerationLock()
2762 2766
	 */
2763 2767
	function releasePageGenerationLock(&$lockObj)	{
2764
		if ($this->no_cache || $this->headerNoCache()) {
2765
			return true;	// No locking is needed if caching is disabled
2766
		}
2767

  
2768 2768
		$success = false;
2769
		if (is_object($lockObj)) {
2769
			// If lock object is set and was aquired (may also happen if no_cache was enabled during runtime), release it:
2770
		if (is_object($lockObj) && $lockObj instanceof t3lib_lock && $lockObj->getLockStatus()) {
2770 2771
			$success = $lockObj->release();
2772
			$lockObj->sysLog('Released lock');
2771 2773
			unset($lockObj);
2774
			// Otherwise, if caching is disabled, no locking is required:
2775
		} elseif ($this->no_cache || $this->headerNoCache()) {
2776
			$success = true; 
2772 2777
		}
2773

  
2774 2778
		return $success;
2775 2779
	}
2776 2780

  
(3-3/4)