diff options
Diffstat (limited to 'src/backend/utils/adt/lockfuncs.c')
-rw-r--r-- | src/backend/utils/adt/lockfuncs.c | 260 |
1 files changed, 257 insertions, 3 deletions
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index 40046a020a0..f7c7deca8d9 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -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(); +} |