mirror of
https://github.com/postgres/postgres.git
synced 2025-12-01 12:18:01 +03:00
Add built-in userlock manipulation functions to replace the former
contrib functionality. Along the way, remove the USER_LOCKS configuration symbol, since it no longer makes any sense to try to compile that out. No user documentation yet ... mmoncure has promised to write some. Thanks to Abhijit Menon-Sen for creating a first draft to work from.
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* lockfuncs.c
|
||||
* Set-returning functions to view the state of locks within the DB.
|
||||
* Functions for SQL access to various lock-manager capabilities.
|
||||
*
|
||||
* Copyright (c) 2002-2006, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.24 2006/07/23 23:08:46 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.25 2006/09/18 22:40:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "funcapi.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "funcapi.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/proc.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
@@ -266,3 +267,256 @@ pg_lock_status(PG_FUNCTION_ARGS)
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Functions for manipulating USERLOCK locks
|
||||
*
|
||||
* We make use of the locktag fields as follows:
|
||||
*
|
||||
* field1: MyDatabaseId ... ensures locks are local to each database
|
||||
* field2: first of 2 int4 keys, or high-order half of an int8 key
|
||||
* field3: second of 2 int4 keys, or low-order half of an int8 key
|
||||
* field4: 1 if using an int8 key, 2 if using 2 int4 keys
|
||||
*/
|
||||
#define SET_LOCKTAG_INT64(tag, key64) \
|
||||
SET_LOCKTAG_USERLOCK(tag, \
|
||||
MyDatabaseId, \
|
||||
(uint32) ((key64) >> 32), \
|
||||
(uint32) (key64), \
|
||||
1)
|
||||
#define SET_LOCKTAG_INT32(tag, key1, key2) \
|
||||
SET_LOCKTAG_USERLOCK(tag, MyDatabaseId, key1, key2, 2)
|
||||
|
||||
/*
|
||||
* pg_advisory_lock(int8) - acquire exclusive lock on an int8 key
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_lock_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, true, false);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_lock_shared(int8) - acquire share lock on an int8 key
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, true, false);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_try_advisory_lock(int8) - acquire exclusive lock on an int8 key, no wait
|
||||
*
|
||||
* Returns true if successful, false if lock not available
|
||||
*/
|
||||
Datum
|
||||
pg_try_advisory_lock_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, true, true);
|
||||
|
||||
PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_try_advisory_lock_shared(int8) - acquire share lock on an int8 key, no wait
|
||||
*
|
||||
* Returns true if successful, false if lock not available
|
||||
*/
|
||||
Datum
|
||||
pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, true, true);
|
||||
|
||||
PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_unlock(int8) - release exclusive lock on an int8 key
|
||||
*
|
||||
* Returns true if successful, false if lock was not held
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_unlock_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockRelease(&tag, ExclusiveLock, true);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_unlock_shared(int8) - release share lock on an int8 key
|
||||
*
|
||||
* Returns true if successful, false if lock was not held
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockRelease(&tag, ShareLock, true);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_lock(int4, int4) - acquire exclusive lock on 2 int4 keys
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_lock_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, true, false);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_lock_shared(int4, int4) - acquire share lock on 2 int4 keys
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, true, false);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_try_advisory_lock(int4, int4) - acquire exclusive lock on 2 int4 keys, no wait
|
||||
*
|
||||
* Returns true if successful, false if lock not available
|
||||
*/
|
||||
Datum
|
||||
pg_try_advisory_lock_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, true, true);
|
||||
|
||||
PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_try_advisory_lock_shared(int4, int4) - acquire share lock on 2 int4 keys, no wait
|
||||
*
|
||||
* Returns true if successful, false if lock not available
|
||||
*/
|
||||
Datum
|
||||
pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, true, true);
|
||||
|
||||
PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_unlock(int4, int4) - release exclusive lock on 2 int4 keys
|
||||
*
|
||||
* Returns true if successful, false if lock was not held
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_unlock_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockRelease(&tag, ExclusiveLock, true);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_unlock_shared(int4, int4) - release share lock on 2 int4 keys
|
||||
*
|
||||
* Returns true if successful, false if lock was not held
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 key1 = PG_GETARG_INT32(0);
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockRelease(&tag, ShareLock, true);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_unlock_all() - release all userlocks
|
||||
*/
|
||||
Datum
|
||||
pg_advisory_unlock_all(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LockReleaseAll(USER_LOCKMETHOD, true);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.169 2006/07/13 16:49:18 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.170 2006/09/18 22:40:38 tgl Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@@ -554,9 +554,7 @@ ShutdownPostgres(int code, Datum arg)
|
||||
* User locks are not released by transaction end, so be sure to release
|
||||
* them explicitly.
|
||||
*/
|
||||
#ifdef USER_LOCKS
|
||||
LockReleaseAll(USER_LOCKMETHOD, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user