Prevent race condition in old threads closing

This commit is contained in:
Dmitriy Simushev 2014-10-29 15:12:05 +00:00
parent b5020645be
commit 96c9bf2a93

View File

@ -373,15 +373,26 @@ class Thread
}
/**
* Close all old threads that were not closed by some reasons
* Close all old threads that were not closed by some reasons.
*/
public static function closeOldThreads()
{
if (Settings::get('thread_lifetime') == 0) {
// Threads live forever.
return;
}
$db = Database::getInstance();
// We need to run only one instance of cleaning process. Use a lock with
// last run timestamp.
$lock_timestamp = (int)Settings::get('_threads_close_old_lock_time', 0);
$is_lock_free = !$lock_timestamp
// Lock cannot be got for more than 5 minutes. If such situation
// take place we have a deadlock.
|| (time() - $lock_timestamp) > 5 * 60;
if ($is_lock_free) {
// Get the lock
Settings::set('_threads_close_old_lock_time', time());
$query = "UPDATE {thread} SET "
. "lrevision = :next_revision, "
@ -395,8 +406,8 @@ class Thread
// Check pings
. "AND ( "
. "( "
// Both user and operator have no connection problems.
// Check all pings.
// Both user and operator have no connection
// problems. Check all pings.
. "lastpingagent <> 0 "
. "AND lastpinguser <> 0 "
. "AND ABS(:now - lastpinguser) > :thread_lifetime "
@ -421,7 +432,8 @@ class Thread
. ") "
. ")";
$db->query(
// Perform the cleaning
Database::getInstance()->query(
$query,
array(
':next_revision' => self::nextRevision(),
@ -431,6 +443,10 @@ class Thread
':thread_lifetime' => Settings::get('thread_lifetime'),
)
);
// Release the lock
Settings::set('_threads_close_old_lock_time', '0');
}
}
/**