3 namespace Drupal\memcache\Lock;
5 use Drupal\Core\Lock\LockBackendAbstract;
6 use Drupal\memcache\DrupalMemcacheInterface;
9 * Defines a Memcache lock backend.
11 class MemcacheLockBackend extends LockBackendAbstract {
14 * An array of currently acquired locks.
18 protected $locks = [];
21 * The bin name for this lock.
28 * The memcache wrapper object.
30 * @var \Drupal\memcache\DrupalMemcacheInterface
35 * Constructs a new MemcacheLockBackend.
38 * The bin name for this lock.
39 * @param \Drupal\memcache\DrupalMemcacheInterface $memcache
40 * The memcache wrapper object.
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();
61 if (isset($this->locks[$name])) {
62 // Try to extend the expiration of a lock we already acquired.
63 $success = !$this->lockMayBeAvailable($name) && $this->memcache->set($name, $lock_id, $timeout);
66 // The lock was broken.
67 unset($this->locks[$name]);
73 if ($this->lockMayBeAvailable($name)) {
74 $success = $this->memcache->add($name, $lock_id, $timeout);
80 // We track all acquired locks in the global variable, if successful.
81 $this->locks[$name] = TRUE;
88 return isset($this->locks[$name]);
94 public function lockMayBeAvailable($name) {
95 return !$this->memcache->get($name);
101 public function release($name) {
102 $this->memcache->delete($name);
103 // We unset unconditionally since caller assumes lock is released anyway.
104 unset($this->locks[$name]);
110 public function releaseAll($lock_id = NULL) {
111 if (empty($lock_id)) {
112 $lock_id = $this->getLockId();
115 foreach ($this->locks as $name => $id) {
116 $value = $this->memcache->get($name);
118 if ($value == $lock_id) {
119 $this->memcache->delete($name);