PluginProbe
InfiniteWP Client / trunk
InfiniteWP Client vtrunk
1.13.10 1.13.7 trunk 0.1.4 0.1.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.11.0 1.11.1 1.12.1 1.12.3 All 92 releases
iwp-client / backup / class.semaphore.php

class.semaphore.php in InfiniteWP Client trunk, at backup/class.semaphore.php

190 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Adapted from WP Social under the GPL - thanks to Alex King (https://github.com/crowdfavorite/wp-social)
3 /**
4 * Semaphore Lock Management
5 */
6
7 if ( ! defined('ABSPATH') )
8 die();
9
10 class IWP_MMB_Semaphore {
11
12 /**
13 * Initializes the semaphore object.
14 *
15 * @static
16 */
17 public static function factory() {
18 return new self;
19 }
20
21 /**
22 * @var bool
23 */
24 protected $lock_broke = false;
25
26 public $lock_name = 'lock';
27
28 /**
29 * Attempts to start the lock. If the rename works, the lock is started.
30 *
31 * @return bool
32 */
33 public function lock() {
34 global $wpdb, $iwp_backup_core,$iwp_mmb_core;
35
36 // Attempt to set the lock
37 $affected = $wpdb->query("
38 UPDATE $wpdb->options
39 SET option_name = 'IWP_locked_".$this->lock_name."'
40 WHERE option_name = 'IWP_unlocked_".$this->lock_name."'
41 ");
42
43 if ($affected == '0' and !$this->stuck_check()) {
44 $iwp_backup_core->log('Semaphore lock ('.$this->lock_name.', '.$wpdb->options.') failed (line '.__LINE__.')');
45 return false;
46 }
47
48 // Check to see if all processes are complete
49 $affected = $wpdb->query("
50 UPDATE $wpdb->options
51 SET option_value = CAST(option_value AS UNSIGNED) + 1
52 WHERE option_name = 'IWP_semaphore_".$this->lock_name."'
53 AND option_value = '0'
54 ");
55 if ($affected != '1') {
56 if (!$this->stuck_check()) {
57 $iwp_backup_core->log('Semaphore lock ('.$this->lock_name.', '.$wpdb->options.') failed (line '.__LINE__.')');
58 return false;
59 }
60
61 // Reset the semaphore to 1
62 $wpdb->query("
63 UPDATE $wpdb->options
64 SET option_value = '1'
65 WHERE option_name = 'IWP_semaphore_".$this->lock_name."'
66 ");
67
68 $iwp_backup_core->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') reset to 1');
69 }
70
71 // Set the lock time
72 $wpdb->query($wpdb->prepare("
73 UPDATE $wpdb->options
74 SET option_value = %s
75 WHERE option_name = 'IWP_last_lock_time_".$this->lock_name."'
76 ", current_time('mysql', 1)));
77 $iwp_backup_core->log('Set semaphore last lock ('.$this->lock_name.') time to '.current_time('mysql', 1));
78
79 $iwp_backup_core->log('Semaphore lock ('.$this->lock_name.') complete');
80 $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '1');
81 $iwp_mmb_core->iwp_delete_option('IWP_running_backupID');
82 return true;
83 }
84
85 /**
86 * Increment the semaphore.
87 *
88 * @param array $filters
89 * @return Social_Semaphore
90 */
91 public function increment(array $filters = array()) {
92 global $wpdb, $iwp_backup_core;
93
94 if (count($filters)) {
95 // Loop through all of the filters and increment the semaphore
96 foreach ($filters as $priority) {
97 for ($i = 0, $j = count($priority); $i < $j; ++$i) {
98 $this->increment();
99 }
100 }
101 }
102 else {
103 $wpdb->query("
104 UPDATE $wpdb->options
105 SET option_value = CAST(option_value AS UNSIGNED) + 1
106 WHERE option_name = 'IWP_semaphore_".$this->lock_name."'
107 ");
108 $iwp_backup_core->log('Incremented the semaphore ('.$this->lock_name.') by 1');
109 }
110
111 return $this;
112 }
113
114 /**
115 * Decrements the semaphore.
116 *
117 * @return void
118 */
119 public function decrement() {
120 global $wpdb, $iwp_backup_core;
121
122 $wpdb->query("
123 UPDATE $wpdb->options
124 SET option_value = CAST(option_value AS UNSIGNED) - 1
125 WHERE option_name = 'IWP_semaphore_".$this->lock_name."'
126 AND CAST(option_value AS UNSIGNED) > 0
127 ");
128 $iwp_backup_core->log('Decremented the semaphore ('.$this->lock_name.') by 1');
129 }
130
131 /**
132 * Unlocks the process.
133 *
134 * @return bool
135 */
136 public function unlock() {
137 global $wpdb, $iwp_backup_core, $iwp_mmb_core;
138
139 // Decrement for the master process.
140 $this->decrement();
141
142 $result = $wpdb->query("
143 UPDATE $wpdb->options
144 SET option_name = 'IWP_unlocked_".$this->lock_name."'
145 WHERE option_name = 'IWP_locked_".$this->lock_name."'
146 ");
147 $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '0');
148 if ($result == '1') {
149 $iwp_backup_core->log('Semaphore ('.$this->lock_name.') unlocked');
150 return true;
151 }
152
153 $iwp_backup_core->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') still locked ('.$result.')');
154 return false;
155 }
156
157 /**
158 * Attempts to jiggle the stuck lock loose.
159 *
160 * @return bool
161 */
162 private function stuck_check() {
163 global $wpdb, $iwp_backup_core;
164
165 // Check to see if we already broke the lock.
166 if ($this->lock_broke) {
167 return true;
168 }
169
170 $current_time = current_time('mysql', 1);
171 $three_minutes_before = gmdate('Y-m-d H:i:s', time()-(defined('IWP_SEMAPHORE_LOCK_WAIT') ? IWP_SEMAPHORE_LOCK_WAIT : 180));
172
173 $affected = $wpdb->query($wpdb->prepare("
174 UPDATE $wpdb->options
175 SET option_value = %s
176 WHERE option_name = 'IWP_last_lock_time_".$this->lock_name."'
177 AND option_value <= %s
178 ", $current_time, $three_minutes_before));
179
180 if ('1' == $affected) {
181 $iwp_backup_core->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') was stuck, set lock time to '.$current_time);
182 $this->lock_broke = true;
183 return true;
184 }
185
186 return false;
187 }
188
189 }
190