xref: /template/strap/ComboStrap/Lock.php (revision a6d63b89429f588dfa170d5ebcaef9d9de191156)
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