diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/storage/lmgr/README | 15 | ||||
-rw-r--r-- | src/backend/storage/lmgr/deadlock.c | 8 | ||||
-rw-r--r-- | src/backend/storage/lmgr/lock.c | 8 | ||||
-rw-r--r-- | src/backend/utils/adt/lockfuncs.c | 260 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 4 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 30 | ||||
-rw-r--r-- | src/include/pg_config_manual.h | 12 | ||||
-rw-r--r-- | src/include/storage/lock.h | 17 | ||||
-rw-r--r-- | src/include/utils/builtins.h | 15 |
10 files changed, 327 insertions, 46 deletions
diff --git a/src/backend/storage/lmgr/README b/src/backend/storage/lmgr/README index 6720a5579f5..8884676d284 100644 --- a/src/backend/storage/lmgr/README +++ b/src/backend/storage/lmgr/README @@ -1,4 +1,4 @@ -$PostgreSQL: pgsql/src/backend/storage/lmgr/README,v 1.20 2006/07/23 23:08:46 tgl Exp $ +$PostgreSQL: pgsql/src/backend/storage/lmgr/README,v 1.21 2006/09/18 22:40:36 tgl Exp $ LOCKING OVERVIEW @@ -48,7 +48,7 @@ The rest of this README file discusses the regular lock manager in detail. LOCK DATA STRUCTURES Lock methods describe the overall locking behavior. Currently there are -two lock methods: DEFAULT and USER. (USER locks are non-blocking.) +two lock methods: DEFAULT and USER. Lock modes describe the type of the lock (read/write or shared/exclusive). In principle, each lock method can have its own set of lock modes with @@ -502,11 +502,6 @@ level by someone. User locks and normal locks are completely orthogonal and they don't interfere with each other. -User locks are always non blocking, therefore they are never acquired if -already held by another process. They must be released explicitly by the -application but they are released automatically when a backend terminates. - -The lockmode parameter can have the same values as for normal locks although -probably only ExclusiveLock can have some practical use. - - DZ - 22 Nov 1997 +User locks are always held as session locks, so that they are not released at +transaction end. They must be released explicitly by the application --- but +they are released automatically when a backend terminates. diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index 0e4acd5c164..f75ca1da4cf 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.41 2006/07/23 23:08:46 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.42 2006/09/18 22:40:36 tgl Exp $ * * Interface: * @@ -873,9 +873,11 @@ DescribeLockTag(StringInfo buf, const LOCKTAG *lock) break; case LOCKTAG_USERLOCK: appendStringInfo(buf, - _("user lock [%u,%u]"), + _("user lock [%u,%u,%u,%u]"), lock->locktag_field1, - lock->locktag_field2); + lock->locktag_field2, + lock->locktag_field3, + lock->locktag_field4); break; default: appendStringInfo(buf, diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index c59999e20ca..6300dc2eeb4 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.172 2006/08/27 19:14:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.173 2006/09/18 22:40:36 tgl Exp $ * * NOTES * A lock table is a shared memory hash table. When @@ -127,8 +127,6 @@ static const LockMethodData default_lockmethod = { #endif }; -#ifdef USER_LOCKS - static const LockMethodData user_lockmethod = { AccessExclusiveLock, /* highest valid lock mode number */ false, @@ -141,17 +139,13 @@ static const LockMethodData user_lockmethod = { #endif }; -#endif /* USER_LOCKS */ - /* * map from lock method id to the lock table data structures */ static const LockMethod LockMethods[] = { NULL, &default_lockmethod, -#ifdef USER_LOCKS &user_lockmethod -#endif }; 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(); +} diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 191082834db..6664755fd3e 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -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 } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index a5f917c371a..f5da840d2d0 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.357 2006/09/16 20:14:33 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.358 2006/09/18 22:40:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200609161 +#define CATALOG_VERSION_NO 200609181 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index af80192686e..1e0dc4b13f5 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.425 2006/09/16 20:14:33 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.426 2006/09/18 22:40:38 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -3946,6 +3946,34 @@ DESCR("contains"); DATA(insert OID = 2749 ( arraycontained PGNSP PGUID 12 f f t f i 2 16 "2277 2277" _null_ _null_ _null_ arraycontained - _null_ )); DESCR("is contained by"); +/* userlock replacements */ +DATA(insert OID = 2880 ( pg_advisory_lock PGNSP PGUID 12 f f t f v 1 2278 "20" _null_ _null_ _null_ pg_advisory_lock_int8 - _null_ )); +DESCR("obtain exclusive advisory lock"); +DATA(insert OID = 2881 ( pg_advisory_lock_shared PGNSP PGUID 12 f f t f v 1 2278 "20" _null_ _null_ _null_ pg_advisory_lock_shared_int8 - _null_ )); +DESCR("obtain shared advisory lock"); +DATA(insert OID = 2882 ( pg_try_advisory_lock PGNSP PGUID 12 f f t f v 1 16 "20" _null_ _null_ _null_ pg_try_advisory_lock_int8 - _null_ )); +DESCR("obtain exclusive advisory lock if available"); +DATA(insert OID = 2883 ( pg_try_advisory_lock_shared PGNSP PGUID 12 f f t f v 1 16 "20" _null_ _null_ _null_ pg_try_advisory_lock_shared_int8 - _null_ )); +DESCR("obtain shared advisory lock if available"); +DATA(insert OID = 2884 ( pg_advisory_unlock PGNSP PGUID 12 f f t f v 1 16 "20" _null_ _null_ _null_ pg_advisory_unlock_int8 - _null_ )); +DESCR("release exclusive advisory lock"); +DATA(insert OID = 2885 ( pg_advisory_unlock_shared PGNSP PGUID 12 f f t f v 1 16 "20" _null_ _null_ _null_ pg_advisory_unlock_shared_int8 - _null_ )); +DESCR("release shared advisory lock"); +DATA(insert OID = 2886 ( pg_advisory_lock PGNSP PGUID 12 f f t f v 2 2278 "23 23" _null_ _null_ _null_ pg_advisory_lock_int4 - _null_ )); +DESCR("obtain exclusive advisory lock"); +DATA(insert OID = 2887 ( pg_advisory_lock_shared PGNSP PGUID 12 f f t f v 2 2278 "23 23" _null_ _null_ _null_ pg_advisory_lock_shared_int4 - _null_ )); +DESCR("obtain shared advisory lock"); +DATA(insert OID = 2888 ( pg_try_advisory_lock PGNSP PGUID 12 f f t f v 2 16 "23 23" _null_ _null_ _null_ pg_try_advisory_lock_int4 - _null_ )); +DESCR("obtain exclusive advisory lock if available"); +DATA(insert OID = 2889 ( pg_try_advisory_lock_shared PGNSP PGUID 12 f f t f v 2 16 "23 23" _null_ _null_ _null_ pg_try_advisory_lock_shared_int4 - _null_ )); +DESCR("obtain shared advisory lock if available"); +DATA(insert OID = 2890 ( pg_advisory_unlock PGNSP PGUID 12 f f t f v 2 16 "23 23" _null_ _null_ _null_ pg_advisory_unlock_int4 - _null_ )); +DESCR("release exclusive advisory lock"); +DATA(insert OID = 2891 ( pg_advisory_unlock_shared PGNSP PGUID 12 f f t f v 2 16 "23 23" _null_ _null_ _null_ pg_advisory_unlock_shared_int4 - _null_ )); +DESCR("release shared advisory lock"); +DATA(insert OID = 2892 ( pg_advisory_unlock_all PGNSP PGUID 12 f f t f v 0 2278 "" _null_ _null_ _null_ pg_advisory_unlock_all - _null_ )); +DESCR("release all advisory locks"); + /* * Symbolic values for provolatile column: these indicate whether the result * of a function is dependent *only* on the values of its explicit arguments, diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 67bcdd730eb..d41d5619966 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -6,7 +6,7 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.22 2006/06/06 17:59:58 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.23 2006/09/18 22:40:40 tgl Exp $ *------------------------------------------------------------------------ */ @@ -101,16 +101,6 @@ /* #define TCL_ARRAYS */ /* - * User locks are handled totally on the application side as long term - * cooperative locks which extend beyond the normal transaction - * boundaries. Their purpose is to indicate to an application that - * someone is `working' on an item. Define this flag to enable user - * locks. You will need the loadable module user-locks.c to use this - * feature. - */ -#define USER_LOCKS - -/* * Define this if you want psql to _always_ ask for a username and a * password for password authentication. */ diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 120fd4f3ca4..ac9a71b8760 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.98 2006/08/27 19:14:34 tgl Exp $ + * $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.99 2006/09/18 22:40:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -146,8 +146,7 @@ typedef enum LockTagType * pg_description, but notice that we are constraining SUBID to 16 bits. * Also, we use DB OID = 0 for shared objects such as tablespaces. */ - LOCKTAG_USERLOCK /* reserved for contrib/userlock */ - /* ID info for a userlock is defined by user_locks.c */ + LOCKTAG_USERLOCK /* advisory "user" locks */ } LockTagType; /* @@ -221,6 +220,14 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_OBJECT, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +#define SET_LOCKTAG_USERLOCK(locktag,id1,id2,id3,id4) \ + ((locktag).locktag_field1 = (id1), \ + (locktag).locktag_field2 = (id2), \ + (locktag).locktag_field3 = (id3), \ + (locktag).locktag_field4 = (id4), \ + (locktag).locktag_type = LOCKTAG_USERLOCK, \ + (locktag).locktag_lockmethodid = USER_LOCKMETHOD) + /* * Per-locked-object lock information: @@ -362,8 +369,8 @@ typedef struct LOCALLOCK /* * This struct holds information passed from lmgr internals to the lock - * listing user-level functions (lockfuncs.c). For each PROCLOCK in the - * system, copies of the PROCLOCK object and associated PGPROC and + * listing user-level functions (in lockfuncs.c). For each PROCLOCK in + * the system, copies of the PROCLOCK object and associated PGPROC and * LOCK objects are stored. Note there will often be multiple copies * of the same PGPROC or LOCK --- to detect whether two are the same, * compare the PROCLOCK tag fields. diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index f0bc0531771..e1ed7b862b3 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.281 2006/07/28 18:33:04 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.282 2006/09/18 22:40:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -892,6 +892,19 @@ extern Datum show_all_settings(PG_FUNCTION_ARGS); /* lockfuncs.c */ extern Datum pg_lock_status(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_all(PG_FUNCTION_ARGS); /* access/transam/twophase.c */ extern Datum pg_prepared_xact(PG_FUNCTION_ARGS); |