]> git.mxchange.org Git - friendica.git/blob - include/lock.php
Merge pull request #375 from fermionic/diaspora-prevent-fcontact-race-conditions
[friendica.git] / include / lock.php
1 <?php
2
3 // Provide some ability to lock a PHP function so that multiple processes
4 // can't run the function concurrently
5 if(! function_exists('lock_function')) {
6 function lock_function($fn_name, $block = true, $wait_sec = 2, $timeout = 30) {
7         if( $wait_sec == 0 )
8                 $wait_sec = 2;  // don't let the user pick a value that's likely to crash the system
9
10         $got_lock = false;
11         $start = time();
12
13         do {
14                 q("LOCK TABLE locks WRITE");
15                 $r = q("SELECT locked FROM locks WHERE name = '%s' LIMIT 1",
16                         dbesc($fn_name)
17                 );
18
19                 if((count($r)) && (! $r[0]['locked'])) {
20                         q("UPDATE locks SET locked = 1 WHERE name = '%s' LIMIT 1",
21                                 dbesc($fn_name)
22                         );
23                         $got_lock = true;
24                 }
25                 elseif(! $r) { // the Boolean value for count($r) should be equivalent to the Boolean value of $r
26                         q("INSERT INTO locks ( name, locked ) VALUES ( '%s', 1 )",
27                                 dbesc($fn_name)
28                         );
29                         $got_lock = true;
30                 }
31
32                 q("UNLOCK TABLES");
33
34                 if(($block) && (! $got_lock))
35                         sleep($wait_sec);
36
37         } while(($block) && (! $got_lock) && ((time() - $start) < $timeout));
38
39         logger('lock_function: function ' . $fn_name . ' with blocking = ' . $block . ' got_lock = ' . $got_lock . ' time = ' . (time() - $start), LOGGER_DEBUG);
40         
41         return $got_lock;
42 }}
43
44
45 if(! function_exists('block_on_function_lock')) {
46 function block_on_function_lock($fn_name, $wait_sec = 2, $timeout = 30) {
47         if( $wait_sec == 0 )
48                 $wait_sec = 2;  // don't let the user pick a value that's likely to crash the system
49
50         $start = time();
51
52         do {
53                 $r = q("SELECT locked FROM locks WHERE name = '%s' LIMIT 1",
54                                 dbesc($fn_name)
55                      );
56
57                 if(count($r) && $r[0]['locked'])
58                         sleep($wait_sec);
59
60         } while(count($r) && $r[0]['locked'] && ((time() - $start) < $timeout));
61
62         return;
63 }}
64
65
66 if(! function_exists('unlock_function')) {
67 function unlock_function($fn_name) {
68         $r = q("UPDATE locks SET locked = 0 WHERE name = '%s' LIMIT 1",
69                         dbesc($fn_name)
70              );
71
72         logger('unlock_function: released lock for function ' . $fn_name, LOGGER_DEBUG);
73
74         return;
75 }}
76
77 ?>