Mutex.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\mutex;
  8. use Yii;
  9. use yii\base\Component;
  10. /**
  11. * @author resurtm <[email protected]>
  12. * @since 2.0
  13. */
  14. abstract class Mutex extends Component
  15. {
  16. /**
  17. * @var boolean whether all locks acquired in this process (i.e. local locks) must be released automagically
  18. * before finishing script execution. Defaults to true. Setting this property to true means that all locks
  19. * acquire in this process must be released in any case (regardless any kind of errors or exceptions).
  20. */
  21. public $autoRelease = true;
  22. /**
  23. * @var string[] names of the locks acquired in the current PHP process.
  24. */
  25. private $_locks = [];
  26. /**
  27. * Initializes the mutex component.
  28. */
  29. public function init()
  30. {
  31. if ($this->autoRelease) {
  32. $locks = &$this->_locks;
  33. register_shutdown_function(function () use (&$locks) {
  34. foreach ($locks as $lock) {
  35. $this->release($lock);
  36. }
  37. });
  38. }
  39. }
  40. /**
  41. * Acquires lock by given name.
  42. * @param string $name of the lock to be acquired. Must be unique.
  43. * @param integer $timeout to wait for lock to be released. Defaults to zero meaning that method will return
  44. * false immediately in case lock was already acquired.
  45. * @return boolean lock acquiring result.
  46. */
  47. public function acquire($name, $timeout = 0)
  48. {
  49. if ($this->acquireLock($name, $timeout)) {
  50. $this->_locks[] = $name;
  51. return true;
  52. } else {
  53. return false;
  54. }
  55. }
  56. /**
  57. * Release acquired lock. This method will return false in case named lock was not found.
  58. * @param string $name of the lock to be released. This lock must be already created.
  59. * @return boolean lock release result: false in case named lock was not found..
  60. */
  61. public function release($name)
  62. {
  63. if ($this->releaseLock($name)) {
  64. $index = array_search($name, $this->_locks);
  65. if ($index !== false) {
  66. unset($this->_locks[$index]);
  67. }
  68. return true;
  69. } else {
  70. return false;
  71. }
  72. }
  73. /**
  74. * This method should be extended by concrete mutex implementations. Acquires lock by given name.
  75. * @param string $name of the lock to be acquired.
  76. * @param integer $timeout to wait for lock to become released.
  77. * @return boolean acquiring result.
  78. */
  79. abstract protected function acquireLock($name, $timeout = 0);
  80. /**
  81. * This method should be extended by concrete mutex implementations. Releases lock by given name.
  82. * @param string $name of the lock to be released.
  83. * @return boolean release result.
  84. */
  85. abstract protected function releaseLock($name);
  86. }