1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Console\Command; 13 14use Symfony\Component\Console\Exception\LogicException; 15use Symfony\Component\Lock\LockFactory; 16use Symfony\Component\Lock\LockInterface; 17use Symfony\Component\Lock\Store\FlockStore; 18use Symfony\Component\Lock\Store\SemaphoreStore; 19 20/** 21 * Basic lock feature for commands. 22 * 23 * @author Geoffrey Brier <geoffrey.brier@gmail.com> 24 */ 25trait LockableTrait 26{ 27 /** @var LockInterface|null */ 28 private $lock; 29 30 /** 31 * Locks a command. 32 */ 33 private function lock(string $name = null, bool $blocking = false): bool 34 { 35 if (!class_exists(SemaphoreStore::class)) { 36 throw new LogicException('To enable the locking feature you must install the symfony/lock component.'); 37 } 38 39 if (null !== $this->lock) { 40 throw new LogicException('A lock is already in place.'); 41 } 42 43 if (SemaphoreStore::isSupported()) { 44 $store = new SemaphoreStore(); 45 } else { 46 $store = new FlockStore(); 47 } 48 49 $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName()); 50 if (!$this->lock->acquire($blocking)) { 51 $this->lock = null; 52 53 return false; 54 } 55 56 return true; 57 } 58 59 /** 60 * Releases the command lock if there is one. 61 */ 62 private function release() 63 { 64 if ($this->lock) { 65 $this->lock->release(); 66 $this->lock = null; 67 } 68 } 69} 70