Skip to content

Commit

Permalink
Updated DB_lockTable() so multiple tables can be locked
Browse files Browse the repository at this point in the history
  • Loading branch information
mystralkk committed Jun 5, 2021
1 parent 8c007f7 commit f0ed16f
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 37 deletions.
2 changes: 1 addition & 1 deletion plugins/polls/functions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ function POLLS_ipAlreadyVoted($pid, $ip = '')

$ip = DB_escapeString($ip);
$pid = DB_escapeString($pid);
$sql = "SELECT COUNT(p.*) AS cnt FROM {$_TABLES['pollvoters']} AS p "
$sql = "SELECT COUNT(*) AS cnt FROM {$_TABLES['pollvoters']} AS p "
. "LEFT JOIN {$_TABLES['ip_addresses']} AS i "
. "ON p.seq = i.seq "
. "WHERE (i.ipaddress = '$ip') AND (p.pid = '$pid')";
Expand Down
2 changes: 1 addition & 1 deletion public_html/lib-common.php
Original file line number Diff line number Diff line change
Expand Up @@ -6140,7 +6140,7 @@ function COM_checkSpeedlimit($type = 'submit', $max = 1, $property = '')
$res = DB_query(
"SELECT s.date FROM {$_TABLES['speedlimit']} AS s "
. "LEFT JOIN {$_TABLES['ip_addresses']} AS i "
. "ON s.seq i.seq "
. "ON s.seq = i.seq "
. "WHERE (s.type = '$type') AND (i.ipaddress = '$property') ORDER BY date ASC"
);

Expand Down
20 changes: 15 additions & 5 deletions system/classes/Database/DbMysqli.php
Original file line number Diff line number Diff line change
Expand Up @@ -954,10 +954,10 @@ public function dbError($sql = '')
}

/**
* Lock a table
* Lock a table/tables
* Locks a table for write operations
*
* @param string $table Table to lock
* @param string|string[] $table Table to lock
* @see dbUnlockTable
*/
public function dbLockTable($table)
Expand All @@ -966,7 +966,17 @@ public function dbLockTable($table)
$this->_errorLog("\n*** Inside database->dbLockTable ***");
}

$sql = "LOCK TABLES {$table} WRITE";
if (is_string($table)) {
$sql = "LOCK TABLES {$table} WRITE";
} else {
foreach ($table as &$t) {
$t = $t . ' WRITE';
}
unset($t);

$sql = "LOCK TABLES " . implode(', ', $table);
}

$this->dbQuery($sql);

if ($this->_verbose) {
Expand All @@ -975,8 +985,8 @@ public function dbLockTable($table)
}

/**
* Unlock a table
* Unlocks a table after a dbLockTable (actually, unlocks all tables)
* Unlock a table/tables
* Unlocks a table/tables after a dbLockTable (actually, unlocks all tables)
*
* @param string $table Table to unlock (ignored)
* @see dbLockTable
Expand Down
10 changes: 5 additions & 5 deletions system/classes/Database/DbPgsql.php
Original file line number Diff line number Diff line change
Expand Up @@ -834,10 +834,10 @@ public function dbInsertId($link_identifier = null, $sequence = '')
}

/**
* Lock a table
* Lock a table/tables
* Locks a table for write operations
*
* @param string $table Table to lock
* @param string|string[] $table Table to lock
* @see dbUnlockTable
*/
public function dbLockTable($table)
Expand All @@ -856,10 +856,10 @@ public function dbLockTable($table)
}

/**
* Unlock a table
* Unlocks a table after a dbLockTable (actually, unlocks all tables)
* Unlock a table/tables
* Unlocks a table/tables after a dbLockTable (actually, unlocks all tables)
*
* @param string $table Table to unlock (ignored)
* @param string|string[] $table Table to unlock (ignored)
* @see dbLockTable
*/
public function dbUnlockTable($table)
Expand Down
8 changes: 4 additions & 4 deletions system/lib-comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,7 @@ function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)

$ret = -1; // comment queued
} elseif ($pid > 0) {
DB_lockTable($_TABLES['comments']);
DB_lockTable([$_TABLES['comments'], $_TABLES['ip_addresses']]);

$result = DB_query("SELECT rht, indent FROM {$_TABLES['comments']} WHERE cid = $pid AND sid = '$sid'");
list($rht, $indent) = DB_fetchArray($result);
Expand Down Expand Up @@ -1548,7 +1548,7 @@ function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
}
$ret = 4; // Cannot return here, tables locked!
}
DB_unlockTable($_TABLES['comments']);
DB_unlockTable([$_TABLES['comments'], $_TABLES['ip_addresses']]);

// If no error then
if ($ret != 4) {
Expand Down Expand Up @@ -1581,7 +1581,7 @@ function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
}
}
} else {
DB_lockTable($_TABLES['comments']);
DB_lockTable([$_TABLES['comments'], $_TABLES['ip_addresses']]);
$rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '$sid'");
if (DB_error()) {
$rht = 0;
Expand All @@ -1602,7 +1602,7 @@ function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
}

$cid = DB_insertId('', $_TABLES['comments'] . '_cid_seq');
DB_unlockTable($_TABLES['comments']);
DB_unlockTable([$_TABLES['comments'], $_TABLES['ip_addresses']]);

// Update Comment Feeds
COM_rdfUpToDateCheck('comment');
Expand Down
12 changes: 6 additions & 6 deletions system/lib-database.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,10 @@ function DB_doDatabaseUpgrade($current_gl_version)
}

/**
* Lock a table
* Locks a table for write operations
* Lock a table/tables
* Locks a table/tables for write operations
*
* @param string $table Table to lock
* @param string|string[] $table Table to lock
* @see DB_unlockTable
*/
function DB_lockTable($table)
Expand All @@ -514,10 +514,10 @@ function DB_lockTable($table)
}

/**
* Unlock a table
* Unlocks a table after DB_lockTable
* Unlock a table/tables
* Unlocks a table/tables after DB_lockTable
*
* @param string $table Table to unlock
* @param string|string[] $table Table to unlock
* @see DB_lockTable
*/
function DB_unlockTable($table)
Expand Down
25 changes: 10 additions & 15 deletions system/lib-sessions.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,16 @@ function SESS_newSession($userId, $remote_ip)
$ctime = time();
$currentTime = (string) $ctime;
$expiryTime = (string) ($ctime - $lifespan);
$deleteResult = false;
$deleteResult1 = true;
$deleteResult2 = true;
$retryMax = 3;
$wait = 50000; // 50 ms

for ($i = 0; $i < $retryMax; $i++) {
DB_lockTable($_TABLES['sessions']);
$sql = "SELECT s.sess_id, i.seq FROM {$_TABLES['sessions']} AS s "
. "LEFT JOIN {$_TABLES['ip_addresses']} AS i "
. "ON s.seq = i.seq "
DB_lockTable([$_TABLES['sessions'], $_TABLES['ip_addresses']]);
$sql = "SELECT sess_id, {$_TABLES['sessions']}.seq FROM {$_TABLES['sessions']} "
. "LEFT JOIN {$_TABLES['ip_addresses']} "
. "ON {$_TABLES['sessions']}.seq = {$_TABLES['ip_addresses']}.seq "
. "WHERE (start_time < {$expiryTime})";
$result = DB_query($sql);
$sessIds = [];
Expand All @@ -308,20 +309,14 @@ function SESS_newSession($userId, $remote_ip)
$seqs[] = (int) $A['seq'];
}

$deleteResult1 = true;

if (!empty($sessIds)) {
$deleteSQL1 = "DELETE FROM {$_TABLES['sessions']} WHERE sess_id IN ('" . implode("', '", $sessIds) . "')";
$deleteResult1 = DB_query($deleteSQL1);
}

$deleteResult2 = true;

if (!empty($seqs)) {
$deleteSQL2 = "DELETE FROM {$_TABLES['ip_addresses']} WHERE seq IN (" . implode(', ', $seqs) . ")";
$deleteResult2 = DB_query($deleteSQL2);
}
DB_unlockTable($_TABLES['sessions']);

DB_unlockTable([$_TABLES['sessions'], $_TABLES['ip_addresses']]);

if ($_SESS_VERBOSE) {
COM_errorLog("Attempted to delete rows from session table with following SQL\n$deleteSQL1\n",1);
Expand All @@ -330,14 +325,14 @@ function SESS_newSession($userId, $remote_ip)
COM_errorLog("Got $deleteResult2 as a result from the query",1);
}

if ($deleteResult1) {
if ($deleteResult1 && $deleteResult2) {
break;
}

usleep($wait);
}

if (!$deleteResult) {
if (!$deleteResult1 || !$deleteResult2) {
die("Delete failed in SESS_newSession()");
}

Expand Down

0 comments on commit f0ed16f

Please sign in to comment.