1: <?php
2: /**
3: * Wei Framework
4: *
5: * @copyright Copyright (c) 2008-2015 Twin Huang
6: * @license http://opensource.org/licenses/mit-license.php MIT License
7: */
8:
9: namespace Wei;
10:
11: /**
12: * A service that provide the functionality of exclusive Lock
13: *
14: * @author Twin Huang <twinhuang@qq.com>
15: * @property Cache $cache A cache service
16: */
17: class Lock extends Base
18: {
19: /**
20: * @var array
21: */
22: protected $keys = array();
23:
24: /**
25: * Constructor
26: *
27: * @param array $options
28: */
29: public function __construct(array $options = array())
30: {
31: parent::__construct($options);
32:
33: register_shutdown_function(array($this, 'releaseAll'));
34:
35: // Release locks and exist when catch signal in CLI
36: if (function_exists('pcntl_signal')) {
37: pcntl_signal(SIGINT, array($this, 'catchSignal'));
38: pcntl_signal(SIGTERM, array($this, 'catchSignal'));
39: }
40: }
41:
42: /**
43: * Acquire a lock key
44: *
45: * @param string $key
46: * @return bool
47: */
48: public function __invoke($key)
49: {
50: if ($this->cache->add($key, true)) {
51: $this->keys[] = $key;
52: return true;
53: } else {
54: return false;
55: }
56: }
57:
58: /**
59: * Release a lock key
60: *
61: * @param string $key
62: * @return bool
63: */
64: public function release($key)
65: {
66: if ($this->cache->remove($key)) {
67: if (($index = array_search($key, $this->keys)) !== false) {
68: unset($this->keys[$index]);
69: }
70: return true;
71: } else {
72: return false;
73: }
74: }
75:
76: /**
77: * Release all lock keys
78: */
79: public function releaseAll()
80: {
81: foreach ($this->keys as $key) {
82: $this->release($key);
83: }
84: }
85:
86: /**
87: * Release all lock keys and exit
88: */
89: public function catchSignal()
90: {
91: $this->releaseAll();
92: exit;
93: }
94: }