1*a6d63b89Sgerardnico<?php 2*a6d63b89Sgerardnico 3*a6d63b89Sgerardniconamespace ComboStrap; 4*a6d63b89Sgerardnico 5*a6d63b89Sgerardnico 6*a6d63b89Sgerardnicouse dokuwiki\Search\Indexer; 7*a6d63b89Sgerardnico 8*a6d63b89Sgerardnico/** 9*a6d63b89Sgerardnico * Adapted from the {@link Indexer::lock()} 10*a6d63b89Sgerardnico * because the TaskRunner does not run serially 11*a6d63b89Sgerardnico * Only the indexer does 12*a6d63b89Sgerardnico * https://forum.dokuwiki.org/d/21044-taskrunner-running-multiple-times-eating-the-memory-lock 13*a6d63b89Sgerardnico */ 14*a6d63b89Sgerardnicoclass Lock 15*a6d63b89Sgerardnico{ 16*a6d63b89Sgerardnico private string $lockName; 17*a6d63b89Sgerardnico private string $lockFile; 18*a6d63b89Sgerardnico /** 19*a6d63b89Sgerardnico * @var mixed|null 20*a6d63b89Sgerardnico */ 21*a6d63b89Sgerardnico private $perm; 22*a6d63b89Sgerardnico 23*a6d63b89Sgerardnico 24*a6d63b89Sgerardnico /** 25*a6d63b89Sgerardnico * @param string $name 26*a6d63b89Sgerardnico */ 27*a6d63b89Sgerardnico public function __construct(string $name) 28*a6d63b89Sgerardnico { 29*a6d63b89Sgerardnico $this->lockName = $name; 30*a6d63b89Sgerardnico global $conf; 31*a6d63b89Sgerardnico $this->lockFile = $conf['lockdir'] . "/_{$this->lockName}.lock"; 32*a6d63b89Sgerardnico $this->perm = $conf['dperm'] ?? null; 33*a6d63b89Sgerardnico } 34*a6d63b89Sgerardnico 35*a6d63b89Sgerardnico public static function create(string $name): Lock 36*a6d63b89Sgerardnico { 37*a6d63b89Sgerardnico return new Lock($name); 38*a6d63b89Sgerardnico } 39*a6d63b89Sgerardnico 40*a6d63b89Sgerardnico /** 41*a6d63b89Sgerardnico * @throws ExceptionTimeOut - with the timeout 42*a6d63b89Sgerardnico */ 43*a6d63b89Sgerardnico function acquire() 44*a6d63b89Sgerardnico { 45*a6d63b89Sgerardnico $run = 0; 46*a6d63b89Sgerardnico while (!@mkdir($this->lockFile)) { 47*a6d63b89Sgerardnico usleep(1000); 48*a6d63b89Sgerardnico /** 49*a6d63b89Sgerardnico * Old lock ? More than 5 minutes run 50*a6d63b89Sgerardnico */ 51*a6d63b89Sgerardnico if (is_dir($this->lockFile) && (time() - @filemtime($this->lockFile)) > 60 * 5) { 52*a6d63b89Sgerardnico if (!@rmdir($this->lockFile)) { 53*a6d63b89Sgerardnico throw new ExceptionRuntimeInternal("Removing the lock failed ($this->lockFile)"); 54*a6d63b89Sgerardnico } 55*a6d63b89Sgerardnico } 56*a6d63b89Sgerardnico if ($run++ == 5) { 57*a6d63b89Sgerardnico // we waited 5 seconds for that lock 58*a6d63b89Sgerardnico throw new ExceptionTimeOut("Unable to get the lock ($this->lockFile)"); 59*a6d63b89Sgerardnico } 60*a6d63b89Sgerardnico } 61*a6d63b89Sgerardnico if ($this->perm) { 62*a6d63b89Sgerardnico chmod($this->lockFile, $this->perm); 63*a6d63b89Sgerardnico } 64*a6d63b89Sgerardnico 65*a6d63b89Sgerardnico } 66*a6d63b89Sgerardnico 67*a6d63b89Sgerardnico /** 68*a6d63b89Sgerardnico * Release the indexer lock. 69*a6d63b89Sgerardnico * 70*a6d63b89Sgerardnico */ 71*a6d63b89Sgerardnico function release() 72*a6d63b89Sgerardnico { 73*a6d63b89Sgerardnico @rmdir($this->lockFile); 74*a6d63b89Sgerardnico } 75*a6d63b89Sgerardnico 76*a6d63b89Sgerardnico} 77