123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <?php
- function lock_initialize() {
- global $locks;
- $locks = array();
- }
- function _lock_id() {
-
-
-
- static $lock_id;
- if (!isset($lock_id)) {
-
- $lock_id = uniqid(mt_rand(), TRUE);
-
- drupal_register_shutdown_function('lock_release_all', $lock_id);
- }
- return $lock_id;
- }
- function lock_acquire($name, $timeout = 30.0) {
- global $locks;
-
- $timeout = max($timeout, 0.001);
- $expire = microtime(TRUE) + $timeout;
- if (isset($locks[$name])) {
-
- $success = (bool) db_update('semaphore')
- ->fields(array('expire' => $expire))
- ->condition('name', $name)
- ->condition('value', _lock_id())
- ->execute();
- if (!$success) {
-
- unset($locks[$name]);
- }
- return $success;
- }
- else {
-
-
- $retry = FALSE;
-
- do {
- try {
- db_insert('semaphore')
- ->fields(array(
- 'name' => $name,
- 'value' => _lock_id(),
- 'expire' => $expire,
- ))
- ->execute();
-
- $locks[$name] = TRUE;
-
- $retry = FALSE;
- }
- catch (PDOException $e) {
-
-
-
-
-
- $retry = $retry ? FALSE : lock_may_be_available($name);
- }
-
-
- } while ($retry);
- }
- return isset($locks[$name]);
- }
- function lock_may_be_available($name) {
- $lock = db_query('SELECT expire, value FROM {semaphore} WHERE name = :name', array(':name' => $name))->fetchAssoc();
- if (!$lock) {
- return TRUE;
- }
- $expire = (float) $lock['expire'];
- $now = microtime(TRUE);
- if ($now > $expire) {
-
-
-
- return (bool) db_delete('semaphore')
- ->condition('name', $name)
- ->condition('value', $lock['value'])
- ->condition('expire', 0.0001 + $expire, '<=')
- ->execute();
- }
- return FALSE;
- }
- function lock_wait($name, $delay = 30) {
-
-
-
-
-
-
-
-
-
-
-
-
- $delay = (int) $delay * 1000000;
-
- $sleep = 25000;
- while ($delay > 0) {
-
-
-
- usleep($sleep);
-
-
- $delay = $delay - $sleep;
- $sleep = min(500000, $sleep + 25000, $delay);
- if (lock_may_be_available($name)) {
-
- return FALSE;
- }
- }
-
- return TRUE;
- }
- function lock_release($name) {
- global $locks;
- unset($locks[$name]);
- db_delete('semaphore')
- ->condition('name', $name)
- ->condition('value', _lock_id())
- ->execute();
- }
- function lock_release_all($lock_id = NULL) {
- global $locks;
- $locks = array();
- if (empty($lock_id)) {
- $lock_id = _lock_id();
- }
- db_delete('semaphore')
- ->condition('value', $lock_id)
- ->execute();
- }
|