MediaWiki  master
PostgreSqlLockManager.php
Go to the documentation of this file.
1 <?php
2 
4 
13  protected $lockTypeMap = [
14  self::LOCK_SH => self::LOCK_SH,
15  self::LOCK_UW => self::LOCK_SH,
16  self::LOCK_EX => self::LOCK_EX
17  ];
18 
19  protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) {
20  $status = StatusValue::newGood();
21  if ( $paths === [] ) {
22  return $status; // nothing to lock
23  }
24 
25  $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
26  $bigints = array_unique( array_map(
27  function ( $key ) {
28  return Wikimedia\base_convert( substr( $key, 0, 15 ), 16, 10 );
29  },
30  array_map( [ $this, 'sha1Base16Absolute' ], $paths )
31  ) );
32 
33  // Try to acquire all the locks...
34  $fields = [];
35  foreach ( $bigints as $bigint ) {
36  $fields[] = ( $type == self::LOCK_SH )
37  ? "pg_try_advisory_lock_shared({$db->addQuotes( $bigint )}) AS K$bigint"
38  : "pg_try_advisory_lock({$db->addQuotes( $bigint )}) AS K$bigint";
39  }
40  $res = $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
41  $row = $res->fetchRow();
42 
43  if ( in_array( 'f', $row ) ) {
44  // Release any acquired locks if some could not be acquired...
45  $fields = [];
46  foreach ( $row as $kbigint => $ok ) {
47  if ( $ok === 't' ) { // locked
48  $bigint = substr( $kbigint, 1 ); // strip off the "K"
49  $fields[] = ( $type == self::LOCK_SH )
50  ? "pg_advisory_unlock_shared({$db->addQuotes( $bigint )})"
51  : "pg_advisory_unlock({$db->addQuotes( $bigint )})";
52  }
53  }
54  if ( count( $fields ) ) {
55  $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
56  }
57  foreach ( $paths as $path ) {
58  $status->fatal( 'lockmanager-fail-acquirelock', $path );
59  }
60  }
61 
62  return $status;
63  }
64 
69  protected function releaseAllLocks() {
70  $status = StatusValue::newGood();
71 
72  foreach ( $this->conns as $lockDb => $db ) {
73  try {
74  $db->query( "SELECT pg_advisory_unlock_all()", __METHOD__ );
75  } catch ( DBError $e ) {
76  $status->fatal( 'lockmanager-fail-db-release', $lockDb );
77  }
78  }
79 
80  return $status;
81  }
82 }
LockManager\LOCK_SH
const LOCK_SH
Lock types; stronger locks have higher values.
Definition: LockManager.php:69
$res
$res
Definition: testCompression.php:57
Wikimedia\Rdbms\DBError
Database error base class @newable Stable to extend.
Definition: DBError.php:32
PostgreSqlLockManager\$lockTypeMap
array $lockTypeMap
Mapping of lock types to the type actually used.
Definition: PostgreSqlLockManager.php:13
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
PostgreSqlLockManager\doGetLocksOnServer
doGetLocksOnServer( $lockSrv, array $paths, $type)
Definition: PostgreSqlLockManager.php:19
$path
$path
Definition: NoLocalSettings.php:25
DBLockManager\getConnection
getConnection( $lockDb)
Get (or reuse) a connection to a lock DB.
Definition: DBLockManager.php:152
DBLockManager
Version of LockManager based on using named/row DB locks.
Definition: DBLockManager.php:43
PostgreSqlLockManager\releaseAllLocks
releaseAllLocks()
Definition: PostgreSqlLockManager.php:69
LockManager\LOCK_EX
const LOCK_EX
Definition: LockManager.php:71
PostgreSqlLockManager
PostgreSQL version of DBLockManager that supports shared locks.
Definition: PostgreSqlLockManager.php:11
$type
$type
Definition: testCompression.php:52