Dropbox2
2 years ago
Google
2 years ago
blockui
1 year ago
checkout-embed
1 year ago
cloudfiles
2 years ago
handlebars
2 years ago
images
9 years ago
jquery-ui.dialog.extended
1 year ago
jquery.serializeJSON
5 years ago
jstree
1 year ago
labelauty
1 year ago
pcloud
2 years ago
tether
6 years ago
tether-shepherd
7 years ago
updraftclone
2 years ago
S3.php
2 years ago
S3compat.php
1 year ago
cacert.pem
2 years ago
class-backup-history.php
1 year ago
class-commands.php
1 year ago
class-database-utility.php
2 years ago
class-filesystem-functions.php
1 year ago
class-http-error-descriptions.php
2 years ago
class-job-scheduler.php
3 years ago
class-manipulation-functions.php
2 years ago
class-partialfileservlet.php
5 years ago
class-remote-send.php
2 years ago
class-search-replace.php
3 years ago
class-semaphore.php
3 years ago
class-storage-methods-interface.php
2 years ago
class-updraft-dashboard-news.php
2 years ago
class-updraft-semaphore.php
4 years ago
class-updraftcentral-updraftplus-commands.php
3 years ago
class-updraftplus-encryption.php
2 years ago
class-wpadmin-commands.php
1 year ago
class-zip.php
2 years ago
ftp.class.php
2 years ago
get-cpanel-quota-usage.pl
12 years ago
google-extensions.php
3 years ago
jquery-ui.custom-v1.11.4-1-24-10.min.css
1 year ago
jquery-ui.custom-v1.11.4-1-24-10.min.css.map
1 year ago
jquery-ui.custom-v1.11.4.css
3 years ago
jquery-ui.custom-v1.12.1-1-24-10.min.css
1 year ago
jquery-ui.custom-v1.12.1-1-24-10.min.css.map
1 year ago
jquery-ui.custom-v1.12.1.css
3 years ago
migrator-lite.php
1 year ago
updraft-admin-common-1-24-10.min.js
1 year ago
updraft-admin-common.js
1 year ago
updraft-restorer-skin-compatibility.php
6 years ago
updraft-restorer-skin.php
3 years ago
updraftcentral.php
2 years ago
updraftplus-clone.php
2 years ago
updraftplus-login.php
7 years ago
updraftplus-notices.php
2 years ago
updraftplus-tour.php
2 years ago
updraftvault.php
3 years ago
class-semaphore.php
225 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Semaphore Lock Management |
| 4 | * Adapted from WP Social under the GPL - thanks to Alex King (https://github.com/crowdfavorite/wp-social) |
| 5 | */ |
| 6 | class UpdraftPlus_Semaphore { |
| 7 | |
| 8 | /** |
| 9 | * Initializes the semaphore object. |
| 10 | * |
| 11 | * @static |
| 12 | * @return UpdraftPlus_Semaphore |
| 13 | */ |
| 14 | public static function factory() { |
| 15 | return new self; |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * Lock Broke |
| 20 | * |
| 21 | * @var boolean |
| 22 | */ |
| 23 | protected $lock_broke = false; |
| 24 | |
| 25 | public $lock_name = 'lock'; |
| 26 | |
| 27 | /** |
| 28 | * Attempts to start the lock. If the rename works, the lock is started. |
| 29 | * |
| 30 | * @return bool |
| 31 | */ |
| 32 | public function lock() { |
| 33 | global $wpdb, $updraftplus; |
| 34 | |
| 35 | // Attempt to set the lock |
| 36 | $affected = $wpdb->query(" |
| 37 | UPDATE $wpdb->options |
| 38 | SET option_name = 'updraftplus_locked_".$this->lock_name."' |
| 39 | WHERE option_name = 'updraftplus_unlocked_".$this->lock_name."' |
| 40 | "); |
| 41 | |
| 42 | if ('0' == $affected && !$this->stuck_check()) { |
| 43 | $updraftplus->log('Semaphore lock ('.$this->lock_name.', '.$wpdb->options.') failed (line '.__LINE__.')'); |
| 44 | return false; |
| 45 | } |
| 46 | |
| 47 | // Check to see if all processes are complete |
| 48 | $affected = $wpdb->query(" |
| 49 | UPDATE $wpdb->options |
| 50 | SET option_value = CAST(option_value AS UNSIGNED) + 1 |
| 51 | WHERE option_name = 'updraftplus_semaphore_".$this->lock_name."' |
| 52 | AND option_value = '0' |
| 53 | "); |
| 54 | if ('1' != $affected) { |
| 55 | if (!$this->stuck_check()) { |
| 56 | $updraftplus->log('Semaphore lock ('.$this->lock_name.', '.$wpdb->options.') failed (line '.__LINE__.')'); |
| 57 | return false; |
| 58 | } |
| 59 | |
| 60 | // Reset the semaphore to 1 |
| 61 | $wpdb->query(" |
| 62 | UPDATE $wpdb->options |
| 63 | SET option_value = '1' |
| 64 | WHERE option_name = 'updraftplus_semaphore_".$this->lock_name."' |
| 65 | "); |
| 66 | |
| 67 | $updraftplus->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') reset to 1'); |
| 68 | } |
| 69 | |
| 70 | // Set the lock time |
| 71 | $wpdb->query($wpdb->prepare(" |
| 72 | UPDATE $wpdb->options |
| 73 | SET option_value = %s |
| 74 | WHERE option_name = 'updraftplus_last_lock_time_".$this->lock_name."' |
| 75 | ", current_time('mysql', 1))); |
| 76 | $updraftplus->log('Set semaphore last lock ('.$this->lock_name.') time to '.current_time('mysql', 1)); |
| 77 | |
| 78 | $updraftplus->log('Semaphore lock ('.$this->lock_name.') complete'); |
| 79 | return true; |
| 80 | } |
| 81 | |
| 82 | public static function ensure_semaphore_exists($semaphore) { |
| 83 | // Make sure the options for semaphores exist |
| 84 | global $wpdb, $updraftplus; |
| 85 | $results = $wpdb->get_results(" |
| 86 | SELECT option_id |
| 87 | FROM $wpdb->options |
| 88 | WHERE option_name IN ('updraftplus_locked_$semaphore', 'updraftplus_unlocked_$semaphore', 'updraftplus_last_lock_time_$semaphore', 'updraftplus_semaphore_$semaphore') |
| 89 | "); |
| 90 | |
| 91 | if (!is_array($results) || count($results) < 3) { |
| 92 | |
| 93 | if (is_array($results) && count($results) > 0) { |
| 94 | $updraftplus->log("Semaphore ($semaphore, ".$wpdb->options.") in an impossible/broken state - fixing (".count($results).")"); |
| 95 | } else { |
| 96 | $updraftplus->log("Semaphore ($semaphore, ".$wpdb->options.") being initialised"); |
| 97 | } |
| 98 | |
| 99 | $wpdb->query(" |
| 100 | DELETE FROM $wpdb->options |
| 101 | WHERE option_name IN ('updraftplus_locked_$semaphore', 'updraftplus_unlocked_$semaphore', 'updraftplus_last_lock_time_$semaphore', 'updraftplus_semaphore_$semaphore') |
| 102 | "); |
| 103 | |
| 104 | $wpdb->query($wpdb->prepare(" |
| 105 | INSERT INTO $wpdb->options (option_name, option_value, autoload) |
| 106 | VALUES |
| 107 | ('updraftplus_unlocked_$semaphore', '1', 'no'), |
| 108 | ('updraftplus_last_lock_time_$semaphore', '%s', 'no'), |
| 109 | ('updraftplus_semaphore_$semaphore', '0', 'no') |
| 110 | ", current_time('mysql', 1))); |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * Increment the semaphore. |
| 116 | * |
| 117 | * @param array $filters |
| 118 | * @return Updraft_Semaphore |
| 119 | */ |
| 120 | public function increment(array $filters = array()) { |
| 121 | global $wpdb, $updraftplus; |
| 122 | |
| 123 | if (count($filters)) { |
| 124 | // Loop through all of the filters and increment the semaphore |
| 125 | foreach ($filters as $priority) { |
| 126 | for ($i = 0, $j = count($priority); $i < $j; ++$i) { |
| 127 | $this->increment(); |
| 128 | } |
| 129 | } |
| 130 | } else { |
| 131 | $wpdb->query(" |
| 132 | UPDATE $wpdb->options |
| 133 | SET option_value = CAST(option_value AS UNSIGNED) + 1 |
| 134 | WHERE option_name = 'updraftplus_semaphore_".$this->lock_name."' |
| 135 | "); |
| 136 | $updraftplus->log('Incremented the semaphore ('.$this->lock_name.') by 1'); |
| 137 | } |
| 138 | |
| 139 | return $this; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Decrements the semaphore. |
| 144 | * |
| 145 | * @return void |
| 146 | */ |
| 147 | public function decrement() { |
| 148 | global $wpdb, $updraftplus; |
| 149 | |
| 150 | $wpdb->query(" |
| 151 | UPDATE $wpdb->options |
| 152 | SET option_value = CAST(option_value AS UNSIGNED) - 1 |
| 153 | WHERE option_name = 'updraftplus_semaphore_".$this->lock_name."' |
| 154 | AND CAST(option_value AS UNSIGNED) > 0 |
| 155 | "); |
| 156 | $updraftplus->log('Decremented the semaphore ('.$this->lock_name.') by 1'); |
| 157 | } |
| 158 | |
| 159 | /** |
| 160 | * Unlocks the process. |
| 161 | * |
| 162 | * @return bool |
| 163 | */ |
| 164 | public function unlock() { |
| 165 | global $wpdb, $updraftplus; |
| 166 | |
| 167 | // Decrement for the master process. |
| 168 | $this->decrement(); |
| 169 | |
| 170 | $result = $wpdb->query(" |
| 171 | UPDATE $wpdb->options |
| 172 | SET option_name = 'updraftplus_unlocked_".$this->lock_name."' |
| 173 | WHERE option_name = 'updraftplus_locked_".$this->lock_name."' |
| 174 | "); |
| 175 | |
| 176 | if ('1' == $result) { |
| 177 | $updraftplus->log('Semaphore ('.$this->lock_name.') unlocked'); |
| 178 | return true; |
| 179 | } |
| 180 | |
| 181 | $updraftplus->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') still locked ('.$result.')'); |
| 182 | return false; |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * Attempts to jiggle the stuck lock loose. |
| 187 | * |
| 188 | * @return bool |
| 189 | */ |
| 190 | private function stuck_check() { |
| 191 | global $wpdb, $updraftplus; |
| 192 | |
| 193 | // Check to see if we already broke the lock. |
| 194 | if ($this->lock_broke) { |
| 195 | return true; |
| 196 | } |
| 197 | |
| 198 | $current_time = current_time('mysql', 1); |
| 199 | $three_minutes_before = gmdate('Y-m-d H:i:s', time()-(defined('UPDRAFTPLUS_SEMAPHORE_LOCK_WAIT') ? UPDRAFTPLUS_SEMAPHORE_LOCK_WAIT : 180)); |
| 200 | |
| 201 | $affected = $wpdb->query($wpdb->prepare(" |
| 202 | UPDATE $wpdb->options |
| 203 | SET option_value = %s |
| 204 | WHERE option_name = 'updraftplus_last_lock_time_".$this->lock_name."' |
| 205 | AND option_value <= %s |
| 206 | ", $current_time, $three_minutes_before)); |
| 207 | |
| 208 | if ('1' == $affected) { |
| 209 | $updraftplus->log('Semaphore ('.$this->lock_name.', '.$wpdb->options.') was stuck, set lock time to '.$current_time); |
| 210 | $this->lock_broke = true; |
| 211 | return true; |
| 212 | } |
| 213 | |
| 214 | // Check if lock is greater that 24 hours |
| 215 | $last_lock_time = strtotime(UpdraftPlus_Options::get_updraft_option('updraftplus_last_lock_time_'.$this->lock_name, $current_time)); |
| 216 | $next_day = strtotime($current_time.' +1 day'); |
| 217 | if ($last_lock_time > $next_day) { |
| 218 | $this->lock_broke = true; |
| 219 | return true; |
| 220 | } |
| 221 | |
| 222 | return false; |
| 223 | } |
| 224 | } // End UpdraftPlus_Semaphore |
| 225 |