]> git.mxchange.org Git - friendica.git/blob - src/Util/Lock.php
e8fa03f7843047497650e2706c97b6bc6d0a14e2
[friendica.git] / src / Util / Lock.php
1 <?php
2
3 namespace Friendica\Util;
4
5 /**
6  * @file src/Util/Lock.php
7  * @brief Functions for preventing parallel execution of functions
8  *
9  */
10
11 use dba;
12 use dbm;
13
14 /**
15  * @brief This class contain Functions for preventing parallel execution of functions
16  */
17 class Lock {
18
19         /**
20          * @brief Sets a lock for a given name
21          *
22          * @param string $fn_name Name of the lock
23          * @param integer $timeout Seconds until we give up
24          * @param integer $wait_sec Time between to lock attempts
25          *
26          * @return boolean Was the lock successful?
27          */
28         public static function set($fn_name, $timeout = 30, $wait_sec = 2) {
29                 if ($wait_sec == 0) {
30                         $wait_sec = 2;
31                 }
32
33                 $got_lock = false;
34                 $start = time();
35
36                 do {
37                         dba::p("LOCK TABLE `locks` WRITE");
38                         $lock = dba::select('locks', array('locked', 'pid'), array('name' => $fn_name), array('limit' => 1));
39
40                         if (dbm::is_result($lock)) {
41                                 if ($lock['locked']) {
42                                         // When the process id isn't used anymore, we can safely claim the lock for us.
43                                         if (!posix_kill($lock['pid'], 0)) {
44                                                 $lock['locked'] = false;
45                                         }
46                                         // We want to lock something that was already locked by us? So we got the lock.
47                                         if ($lock['pid'] == getmypid()) {
48                                                 $got_lock = true;
49                                         }
50                                 }
51                                 if (!$lock['locked']) {
52                                         dba::update('locks', array('locked' => true, 'pid' => getmypid()), array('name' => $fn_name));
53                                         $got_lock = true;
54                                 }
55                         } elseif (!dbm::is_result($lock)) {
56                                 dba::insert('locks', array('name' => $fn_name, 'locked' => true, 'pid' => getmypid()));
57                                 $got_lock = true;
58                         }
59
60                         dba::p("UNLOCK TABLES");
61
62                         if (!$got_lock) {
63                                 sleep($wait_sec);
64                         }
65                 } while (!$got_lock AND ((time() - $start) < $timeout));
66
67                 return $got_lock;
68         }
69
70         /**
71          * @brief Removes a lock if it was set by us
72          *
73          * @param string $fn_name Name of the lock
74          */
75         public static function remove($fn_name) {
76                 dba::update('locks', array('locked' => false, 'pid' => 0), array('name' => $fn_name, 'pid' => getmypid()));
77                 return;
78         }
79 }