5 * Contains \Drupal\memcache\MemcacheLockBackend.
8 namespace Drupal\memcache\Lock;
10 use Drupal\Core\Lock\LockBackendAbstract;
11 use Drupal\memcache\DrupalMemcacheInterface;
14 * Defines a Memcache lock backend.
16 class MemcacheLockBackend extends LockBackendAbstract {
19 * An array of currently acquired locks.
23 protected $locks = array();
26 * The bin name for this lock.
33 * The memcache wrapper object.
35 * @var \Drupal\memcache\DrupalMemcacheInterface
40 * Constructs a new MemcacheLockBackend.
42 public function __construct($bin, DrupalMemcacheInterface $memcache) {
44 $this->memcache = $memcache;
46 // __destruct() is causing problems with garbage collections, register a
47 // shutdown function instead.
48 drupal_register_shutdown_function([$this, 'releaseAll']);
54 public function acquire($name, $timeout = 30.0) {
55 // Ensure that the timeout is at least 1 sec. This is a limitation imposed
57 $timeout = (int) max($timeout, 1);
59 $lock_id = $this->getLockId();
60 $key = $this->getKey($name);
62 if (isset($this->locks[$name])) {
63 // Try to extend the expiration of a lock we already acquired.
64 $success = !$this->lockMayBeAvailable($name) && $this->memcache->set($key, $lock_id, $timeout);
67 // The lock was broken.
68 unset($this->locks[$name]);
74 if ($this->lockMayBeAvailable($name)) {
75 $success = $this->memcache->set($key, $lock_id, $timeout);
81 // We track all acquired locks in the global variable, if successful.
82 $this->locks[$name] = TRUE;
89 return isset($this->locks[$name]);
95 public function lockMayBeAvailable($name) {
96 return !$this->memcache->get($this->getKey($name));
102 public function release($name) {
103 $this->memcache->delete($this->getKey($name));
104 // We unset unconditionally since caller assumes lock is released anyway.
105 unset($this->locks[$name]);
111 public function releaseAll($lock_id = NULL) {
112 if (empty($lock_id)) {
113 $lock_id = $this->getLockId();
116 foreach ($this->locks as $name => $id) {
117 $key = $this->getKey($name);
118 $value = $this->memcache->get($key);
120 if ($value == $lock_id) {
121 $this->memcache->delete($key);
129 * Gets a storage key based on the lock name.
131 protected function getKey($name) {
132 return 'lock:' . $this->bin . ':' . $name;