wiki.techinc.nl/includes/libs/lockmanager/PostgreSqlLockManager.php
Thiemo Kreuz 734a969d55 Safe replacement of a lot of !count() with === []
This was originally a global search and replace. I manually checked all
replacements and reverted them if (due to the lack of type hints) either
null (that would be 0 when counted) or a Countable object can end in the
variable or property in question.

Now this patch only touches places where I'm sure nothing can break.

For the sanity of the honorable reviewers this patch is exclusively touching
negated counts. You should not find a single `!== []` in this patch, that
would be a mistake.

Change-Id: I5eafd4d8fccdb53a668be8e6f25a566f9c3a0a95
2019-01-15 17:28:49 +01:00

82 lines
2.3 KiB
PHP

<?php
use Wikimedia\Rdbms\DBError;
/**
* PostgreSQL version of DBLockManager that supports shared locks.
* All locks are non-blocking, which avoids deadlocks.
*
* @ingroup LockManager
*/
class PostgreSqlLockManager extends DBLockManager {
/** @var array Mapping of lock types to the type actually used */
protected $lockTypeMap = [
self::LOCK_SH => self::LOCK_SH,
self::LOCK_UW => self::LOCK_SH,
self::LOCK_EX => self::LOCK_EX
];
protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) {
$status = StatusValue::newGood();
if ( $paths === [] ) {
return $status; // nothing to lock
}
$db = $this->getConnection( $lockSrv ); // checked in isServerUp()
$bigints = array_unique( array_map(
function ( $key ) {
return Wikimedia\base_convert( substr( $key, 0, 15 ), 16, 10 );
},
array_map( [ $this, 'sha1Base16Absolute' ], $paths )
) );
// Try to acquire all the locks...
$fields = [];
foreach ( $bigints as $bigint ) {
$fields[] = ( $type == self::LOCK_SH )
? "pg_try_advisory_lock_shared({$db->addQuotes( $bigint )}) AS K$bigint"
: "pg_try_advisory_lock({$db->addQuotes( $bigint )}) AS K$bigint";
}
$res = $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
$row = $res->fetchRow();
if ( in_array( 'f', $row ) ) {
// Release any acquired locks if some could not be acquired...
$fields = [];
foreach ( $row as $kbigint => $ok ) {
if ( $ok === 't' ) { // locked
$bigint = substr( $kbigint, 1 ); // strip off the "K"
$fields[] = ( $type == self::LOCK_SH )
? "pg_advisory_unlock_shared({$db->addQuotes( $bigint )})"
: "pg_advisory_unlock({$db->addQuotes( $bigint )})";
}
}
if ( count( $fields ) ) {
$db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
}
foreach ( $paths as $path ) {
$status->fatal( 'lockmanager-fail-acquirelock', $path );
}
}
return $status;
}
/**
* @see QuorumLockManager::releaseAllLocks()
* @return StatusValue
*/
protected function releaseAllLocks() {
$status = StatusValue::newGood();
foreach ( $this->conns as $lockDb => $db ) {
try {
$db->query( "SELECT pg_advisory_unlock_all()", __METHOD__ );
} catch ( DBError $e ) {
$status->fatal( 'lockmanager-fail-db-release', $lockDb );
}
}
return $status;
}
}