+ /**
+ * Creates a lock using WordPress options.
+ *
+ * @since 4.5.0
+ * @access public
+ * @static
+ *
+ * @param string $lock_name The name of this unique lock.
+ * @param int $release_timeout Optional. The duration in seconds to respect an existing lock.
+ * Default: 1 hour.
+ * @return bool False if a lock couldn't be created or if the lock is no longer valid. True otherwise.
+ */
+ public static function create_lock( $lock_name, $release_timeout = null ) {
+ global $wpdb;
+ if ( ! $release_timeout ) {
+ $release_timeout = HOUR_IN_SECONDS;
+ }
+ $lock_option = $lock_name . '.lock';
+
+ // Try to lock.
+ $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() ) );
+
+ if ( ! $lock_result ) {
+ $lock_result = get_option( $lock_option );
+
+ // If a lock couldn't be created, and there isn't a lock, bail.
+ if ( ! $lock_result ) {
+ return false;
+ }
+
+ // Check to see if the lock is still valid. If not, bail.
+ if ( $lock_result > ( time() - $release_timeout ) ) {
+ return false;
+ }
+
+ // There must exist an expired lock, clear it and re-gain it.
+ WP_Upgrader::release_lock( $lock_name );
+
+ return WP_Upgrader::create_lock( $lock_name, $release_timeout );
+ }
+
+ // Update the lock, as by this point we've definitely got a lock, just need to fire the actions.
+ update_option( $lock_option, time() );
+
+ return true;
+ }
+
+ /**
+ * Releases an upgrader lock.
+ *
+ * @since 4.5.0
+ * @access public
+ * @static
+ *
+ * @see WP_Upgrader::create_lock()
+ *
+ * @param string $lock_name The name of this unique lock.
+ * @return bool True if the lock was successfully released. False on failure.
+ */
+ public static function release_lock( $lock_name ) {
+ return delete_option( $lock_name . '.lock' );
+ }
+