On 1/23/2011 4:24 AM, Robert Haas wrote:
On Thu, Jan 20, 2011 at 5:22 AM, Marko Tiikkaja
<marko.tiikk...@cs.helsinki.fi>  wrote:
On 2011-01-17 9:28 AM +0200, Itagaki Takahiro wrote:
== Coding ==
I expect documentation will come soon.

I'm sorry about this, I have been occupied with other stuff.  I'm going to
work on this tonight.

Any update on this?

Again, my apologies for the delay :-( Things haven't been going as planned during the last few weeks.

Here's an updated patch with proposed doc changes. I still didn't address the issue with pg_advisory_unlock_all() releasing transaction scoped locks, but I'm going to. Another issue I found while testing the behaviour here:
http://archives.postgresql.org/pgsql-hackers/2011-01/msg01939.php
is that if a session holds both a transaction level and a session level lock on the same resource, only one of them will appear in pg_locks. Is that going to be a problem from the user's perspective? Could it be an indication of a well-hidden bug? Based on my tests it seems to work, but I'm not at all confident with the code.


Regards,
Marko Tiikkaja
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 14544,14634 **** SELECT (pg_stat_file('filename')).modification;
          <literal><function>pg_advisory_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain exclusive advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock(<parameter>key1</> <type>int</>, 
<parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain exclusive advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain shared advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain shared advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release an exclusive advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release an exclusive advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_all()</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Release all advisory locks held by the current session</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release a shared advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release a shared advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive advisory lock if available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive advisory lock if available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain shared advisory lock if available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain shared advisory lock if available</entry>
        </row>
       </tbody>
      </tgroup>
--- 14544,14690 ----
          <literal><function>pg_advisory_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain exclusive session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock(<parameter>key1</> <type>int</>, 
<parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain exclusive session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain shared session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Obtain shared session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release an exclusive session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release an exclusive session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_all()</function></literal>
         </entry>
         <entry><type>void</type></entry>
!        <entry>Release all session level advisory locks held by the current 
session</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release a shared session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_advisory_unlock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Release a shared session level advisory lock</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive session level advisory lock if 
available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive session level advisory lock if 
available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain shared session level advisory lock if available</entry>
        </row>
        <row>
         <entry>
          <literal><function>pg_try_advisory_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
         </entry>
         <entry><type>boolean</type></entry>
!        <entry>Obtain shared session level advisory lock if available</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_advisory_xact_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
!        </entry>
!        <entry><type>void</type></entry>
!        <entry>Obtain exclusive transaction level advisory lock</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_advisory_xact_lock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
!        </entry>
!        <entry><type>void</type></entry>
!        <entry>Obtain exclusive transaction level advisory lock</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_advisory_xact_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
!        </entry>
!        <entry><type>void</type></entry>
!        <entry>Obtain shared transaction level advisory lock</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_advisory_xact_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
!        </entry>
!        <entry><type>void</type></entry>
!        <entry>Obtain shared advisory lock for the current transaction</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_try_advisory_xact_lock(<parameter>key</> 
<type>bigint</>)</function></literal>
!        </entry>
!        <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive transaction level advisory lock if 
available</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_try_advisory_xact_lock(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
!        </entry>
!        <entry><type>boolean</type></entry>
!        <entry>Obtain exclusive transaction level advisory lock if 
available</entry>
!       </row>
!       <row>
!        <entry>
!         <literal><function>pg_try_advisory_xact_lock_shared(<parameter>key</> 
<type>bigint</>)</function></literal>
!        </entry>
!        <entry><type>boolean</type></entry>
!        <entry>Obtain shared transaction level advisory lock if 
available</entry>
!       </row>
!       <row>
!        <entry>
!         
<literal><function>pg_try_advisory_xact_lock_shared(<parameter>key1</> 
<type>int</>, <parameter>key2</> <type>int</>)</function></literal>
!        </entry>
!        <entry><type>boolean</type></entry>
!        <entry>Obtain shared transaction level advisory lock if 
available</entry>
        </row>
       </tbody>
      </tgroup>
***************
*** 14680,14690 **** SELECT (pg_stat_file('filename')).modification;
     </para>
  
     <indexterm>
      <primary>pg_advisory_unlock</primary>
     </indexterm>
     <para>
      <function>pg_advisory_unlock</> will release a previously-acquired
!     exclusive advisory lock.  It
      returns <literal>true</> if the lock is successfully released.
      If the lock was not held, it will return <literal>false</>,
      and in addition, an SQL warning will be raised by the server.
--- 14736,14784 ----
     </para>
  
     <indexterm>
+     <primary>pg_advisory_xact_lock</primary>
+    </indexterm>
+    <para>
+     <function>pg_advisory_xact_lock</> works the same as pg_advisory_lock,
+     expect the lock is automatically released at the end of the current
+     transaction and can not be released explicitly.
+    </para>
+ 
+    <indexterm>
+     <primary>pg_advisory_xact_lock_shared</primary>
+    </indexterm>
+    <para>
+     <function>pg_advisory_xact_lock_shared</> works the same as
+     pg_advisory_lock_shared, expect the lock is automatically released at the
+     end of the current transaction and can not be released explicitly.
+    </para>
+ 
+    <indexterm>
+     <primary>pg_try_advisory_xact_lock</primary>
+    </indexterm>
+    <para>
+     <function>pg_try_advisory_xact_lock</> works the same as
+     pg_try_advisory_lock, expect the lock, if acquired, is automatically
+     released at the end of the current transaction and can not be released
+     explicitly.
+    </para>
+ 
+    <indexterm>
+     <primary>pg_try_advisory_xact_lock_shared</primary>
+    </indexterm>
+    <para>
+     <function>pg_try_advisory_xact_lock_shared</> works the same as
+     pg_try_advisory_lock_shared, expect the lock, if acquired, is 
automatically
+     released at the end of the current transaction and can not be released
+     explicitly.
+    </para>
+ 
+    <indexterm>
      <primary>pg_advisory_unlock</primary>
     </indexterm>
     <para>
      <function>pg_advisory_unlock</> will release a previously-acquired
!     exclusive session level advisory lock.  It
      returns <literal>true</> if the lock is successfully released.
      If the lock was not held, it will return <literal>false</>,
      and in addition, an SQL warning will be raised by the server.
***************
*** 14696,14710 **** SELECT (pg_stat_file('filename')).modification;
     <para>
      <function>pg_advisory_unlock_shared</> works the same as
      <function>pg_advisory_unlock</>,
!     except it releases a shared advisory lock.
     </para>
  
     <indexterm>
      <primary>pg_advisory_unlock_all</primary>
     </indexterm>
     <para>
!     <function>pg_advisory_unlock_all</> will release all advisory locks
!     held by the current session.  (This function is implicitly invoked
      at session end, even if the client disconnects ungracefully.)
     </para>
  
--- 14790,14804 ----
     <para>
      <function>pg_advisory_unlock_shared</> works the same as
      <function>pg_advisory_unlock</>,
!     except it releases a shared session level advisory lock.
     </para>
  
     <indexterm>
      <primary>pg_advisory_unlock_all</primary>
     </indexterm>
     <para>
!     <function>pg_advisory_unlock_all</> will release all session level 
advisory
!     locks held by the current session.  (This function is implicitly invoked
      at session end, even if the client disconnects ungracefully.)
     </para>
  
*** a/doc/src/sgml/mvcc.sgml
--- b/doc/src/sgml/mvcc.sgml
***************
*** 1038,1056 **** UPDATE accounts SET balance = balance - 100.00 WHERE acctnum 
= 22222;
       called <firstterm>advisory locks</>, because the system does not
       enforce their use &mdash; it is up to the application to use them
       correctly.  Advisory locks can be useful for locking strategies
!      that are an awkward fit for the MVCC model.  Once acquired, an
!      advisory lock is held until explicitly released or the session ends.
!      Unlike standard locks, advisory locks do not
!      honor transaction semantics: a lock acquired during a
!      transaction that is later rolled back will still be held following the
       rollback, and likewise an unlock is effective even if the calling
!      transaction fails later.  The same lock can be acquired multiple times by
!      its owning process: for each lock request there must be a corresponding
!      unlock request before the lock is actually released.  (If a session
!      already holds a given lock, additional requests will always succeed, even
!      if other sessions are awaiting the lock.)  Like all locks in
!      <productname>PostgreSQL</productname>, a complete list of advisory
!      locks currently held by any session can be found in the
       <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
       system view.
      </para>
--- 1038,1065 ----
       called <firstterm>advisory locks</>, because the system does not
       enforce their use &mdash; it is up to the application to use them
       correctly.  Advisory locks can be useful for locking strategies
!      that are an awkward fit for the MVCC model.</para>
! 
!     <para>
!      There are two different types of advisory locks in
!      <productname>PostgreSQL</productname>: session level and transaction 
level.
!      Once acquired, a session level advisory lock is held until explicitly
!      released or the session ends.  Unlike standard locks, session level
!      advisory locks do not honor transaction semantics: a lock acquired during
!      a transaction that is later rolled back will still be held following the
       rollback, and likewise an unlock is effective even if the calling
!      transaction fails later.  The same session level lock can be acquired
!      multiple times by its owning process: for each lock request there must be
!      a corresponding unlock request before the lock is actually released.  
(If a
!      session already holds a given lock, additional requests will always 
succeed,
!      even if other sessions are awaiting the lock.)  Transaction level locks 
on
!      the other hand behave more like regular locks; they are automatically
!      released at the end of the transaction, and can not be explicitly 
unlocked.
!      Session and transaction level locks share the same lock space, which 
means
!      that a transaction level lock will prevent another session from obtaining
!      a session level lock on that same resource and vice versa.
!      Like all locks in <productname>PostgreSQL</productname>, a complete list 
of
!      advisory locks currently held by any session can be found in the
       <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
       system view.
      </para>
***************
*** 1072,1078 **** UPDATE accounts SET balance = balance - 100.00 WHERE acctnum 
= 22222;
       strategies typical of so called <quote>flat file</> data management
       systems.
       While a flag stored in a table could be used for the same purpose,
!      advisory locks are faster, avoid MVCC bloat, and are automatically
       cleaned up by the server at the end of the session.
       In certain cases using this advisory locking method, especially in 
queries
       involving explicit ordering and <literal>LIMIT</> clauses, care must be
--- 1081,1087 ----
       strategies typical of so called <quote>flat file</> data management
       systems.
       While a flag stored in a table could be used for the same purpose,
!      advisory locks are faster, avoid MVCC bloat, and can be automatically
       cleaned up by the server at the end of the session.
       In certain cases using this advisory locking method, especially in 
queries
       involving explicit ordering and <literal>LIMIT</> clauses, care must be
*** a/src/backend/storage/lmgr/README
--- b/src/backend/storage/lmgr/README
***************
*** 503,523 **** User Locks
  ----------
  
  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.  So it is possible to put an user lock on a tuple's oid,
! retrieve the tuple, work on it for an hour and then update it and remove
! the lock.  While the lock is active other clients can still read and write
! the tuple but they can be aware that it has been locked at the application
! level by someone.
  
  User locks and normal locks are completely orthogonal and they don't
  interfere with each other.
  
- 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.
- 
  Locking during Hot Standby
  --------------------------
  
--- 503,520 ----
  ----------
  
  User locks are handled totally on the application side as long term
! cooperative locks which may extend beyond the normal transaction
! boundaries.  Their purpose is to indicate to an application that someone
! is `working' on an item.  So it is possible to put a user lock on a
! tuple's oid, retrieve the tuple, work on it for an hour and then update it
! and remove the lock.  While the lock is active other clients can still
! read and write the tuple but they can be aware that it has been locked at
! the application level by someone.  It is also possible to obtain user locks
! so that the the lock is released automatically at the end of the transaction.
  
  User locks and normal locks are completely orthogonal and they don't
  interfere with each other.
  
  Locking during Hot Standby
  --------------------------
  
*** a/src/backend/storage/lmgr/lock.c
--- b/src/backend/storage/lmgr/lock.c
***************
*** 130,136 **** static const LockMethodData default_lockmethod = {
  
  static const LockMethodData user_lockmethod = {
        AccessExclusiveLock,            /* highest valid lock mode number */
!       false,
        LockConflicts,
        lock_mode_names,
  #ifdef LOCK_DEBUG
--- 130,136 ----
  
  static const LockMethodData user_lockmethod = {
        AccessExclusiveLock,            /* highest valid lock mode number */
!       true,
        LockConflicts,
        lock_mode_names,
  #ifdef LOCK_DEBUG
*** a/src/backend/storage/lmgr/proc.c
--- b/src/backend/storage/lmgr/proc.c
***************
*** 629,636 **** LockWaitCancel(void)
   * At subtransaction abort, we release all locks held by the subtransaction;
   * this is implemented by retail releasing of the locks under control of
   * the ResourceOwner mechanism.
-  *
-  * Note that user locks are not released in any case.
   */
  void
  ProcReleaseLocks(bool isCommit)
--- 629,634 ----
***************
*** 641,646 **** ProcReleaseLocks(bool isCommit)
--- 639,647 ----
        LockWaitCancel();
        /* Release locks */
        LockReleaseAll(DEFAULT_LOCKMETHOD, !isCommit);
+ 
+       /* Release transaction level advisory locks */
+       LockReleaseAll(USER_LOCKMETHOD, false);
  }
  
  
*** a/src/backend/utils/adt/lockfuncs.c
--- b/src/backend/utils/adt/lockfuncs.c
***************
*** 343,348 **** pg_advisory_lock_int8(PG_FUNCTION_ARGS)
--- 343,365 ----
  }
  
  /*
+  * pg_advisory_xact_lock(int8) - acquire xact scoped
+  * exclusive lock on an int8 key
+  */
+ Datum
+ pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
+ {
+       int64           key = PG_GETARG_INT64(0);
+       LOCKTAG         tag;
+ 
+       SET_LOCKTAG_INT64(tag, key);
+ 
+       (void) LockAcquire(&tag, ExclusiveLock, false, false);
+ 
+       PG_RETURN_VOID();
+ }
+ 
+ /*
   * pg_advisory_lock_shared(int8) - acquire share lock on an int8 key
   */
  Datum
***************
*** 359,364 **** pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
--- 376,398 ----
  }
  
  /*
+  * pg_advisory_xact_lock_shared(int8) - acquire xact scoped
+  * share lock on an int8 key
+  */
+ Datum
+ pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS)
+ {
+       int64           key = PG_GETARG_INT64(0);
+       LOCKTAG         tag;
+ 
+       SET_LOCKTAG_INT64(tag, key);
+ 
+       (void) LockAcquire(&tag, ShareLock, false, 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
***************
*** 378,383 **** pg_try_advisory_lock_int8(PG_FUNCTION_ARGS)
--- 412,437 ----
  }
  
  /*
+  * pg_try_advisory_xact_lock(int8) - acquire xact scoped
+  * exclusive lock on an int8 key, no wait
+  *
+  * Returns true if successful, false if lock not available
+  */
+ Datum
+ pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
+ {
+       int64           key = PG_GETARG_INT64(0);
+       LOCKTAG         tag;
+       LockAcquireResult res;
+ 
+       SET_LOCKTAG_INT64(tag, key);
+ 
+       res = LockAcquire(&tag, ExclusiveLock, false, 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
***************
*** 397,402 **** pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
--- 451,476 ----
  }
  
  /*
+  * pg_try_advisory_xact_lock_shared(int8) - acquire xact scoped
+  * share lock on an int8 key, no wait
+  *
+  * Returns true if successful, false if lock not available
+  */
+ Datum
+ pg_try_advisory_xact_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, false, 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
***************
*** 452,457 **** pg_advisory_lock_int4(PG_FUNCTION_ARGS)
--- 526,549 ----
  }
  
  /*
+  * pg_advisory_xact_lock(int4, int4) - acquire xact scoped
+  * exclusive lock on 2 int4 keys
+  */
+ Datum
+ pg_advisory_xact_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, false, false);
+ 
+       PG_RETURN_VOID();
+ }
+ 
+ /*
   * pg_advisory_lock_shared(int4, int4) - acquire share lock on 2 int4 keys
   */
  Datum
***************
*** 469,474 **** pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
--- 561,584 ----
  }
  
  /*
+  * pg_advisory_xact_lock_shared(int4, int4) - acquire xact scoped
+  * share lock on 2 int4 keys
+  */
+ Datum
+ pg_advisory_xact_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, false, 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
***************
*** 489,494 **** pg_try_advisory_lock_int4(PG_FUNCTION_ARGS)
--- 599,625 ----
  }
  
  /*
+  * pg_try_advisory_xact_lock(int4, int4) - acquire xact scoped
+  * exclusive lock on 2 int4 keys, no wait
+  *
+  * Returns true if successful, false if lock not available
+  */
+ Datum
+ pg_try_advisory_xact_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, false, 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
***************
*** 509,514 **** pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
--- 640,666 ----
  }
  
  /*
+  * pg_try_advisory_xact_lock_shared(int4, int4) - acquire xact scoped
+  * share lock on 2 int4 keys, no wait
+  *
+  * Returns true if successful, false if lock not available
+  */
+ Datum
+ pg_try_advisory_xact_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, false, 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
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 4404,4428 **** DESCR("is contained by");
--- 4404,4444 ----
  
  /* userlock replacements */
  DATA(insert OID = 2880 (  pg_advisory_lock                            PGNSP 
PGUID 12 1 0 0 f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ 
pg_advisory_lock_int8 _null_ _null_ _null_ ));
+ DESCR("obtain exclusive a4dvisory lock");
+ DATA(insert OID = 3071 (  pg_advisory_xact_lock                               
PGNSP PGUID 12 1 0 0 f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ 
pg_advisory_xact_lock_int8 _null_ _null_ _null_ ));
  DESCR("obtain exclusive advisory lock");
  DATA(insert OID = 2881 (  pg_advisory_lock_shared             PGNSP PGUID 12 
1 0 0 f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ 
pg_advisory_lock_shared_int8 _null_ _null_ _null_ ));
  DESCR("obtain shared advisory lock");
+ DATA(insert OID = 3072 (  pg_advisory_xact_lock_shared                PGNSP 
PGUID 12 1 0 0 f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ 
pg_advisory_xact_lock_shared_int8 _null_ _null_ _null_ ));
+ DESCR("obtain shared advisory lock");
  DATA(insert OID = 2882 (  pg_try_advisory_lock                        PGNSP 
PGUID 12 1 0 0 f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_try_advisory_lock_int8 _null_ _null_ _null_ ));
  DESCR("obtain exclusive advisory lock if available");
+ DATA(insert OID = 3073 (  pg_try_advisory_xact_lock                   PGNSP 
PGUID 12 1 0 0 f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_try_advisory_xact_lock_int8 _null_ _null_ _null_ ));
+ DESCR("obtain exclusive advisory lock if available");
  DATA(insert OID = 2883 (  pg_try_advisory_lock_shared PGNSP PGUID 12 1 0 0 f 
f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_try_advisory_lock_shared_int8 _null_ _null_ _null_ ));
  DESCR("obtain shared advisory lock if available");
+ DATA(insert OID = 3074 (  pg_try_advisory_xact_lock_shared    PGNSP PGUID 12 
1 0 0 f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_try_advisory_xact_lock_shared_int8 _null_ _null_ _null_ ));
+ DESCR("obtain shared advisory lock if available");
  DATA(insert OID = 2884 (  pg_advisory_unlock                  PGNSP PGUID 12 
1 0 0 f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_advisory_unlock_int8 _null_ _null_ _null_ ));
  DESCR("release exclusive advisory lock");
  DATA(insert OID = 2885 (  pg_advisory_unlock_shared           PGNSP PGUID 12 
1 0 0 f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ 
pg_advisory_unlock_shared_int8 _null_ _null_ _null_ ));
  DESCR("release shared advisory lock");
  DATA(insert OID = 2886 (  pg_advisory_lock                            PGNSP 
PGUID 12 1 0 0 f f f t f v 2 0 2278 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_lock_int4 _null_ _null_ _null_ ));
  DESCR("obtain exclusive advisory lock");
+ DATA(insert OID = 3075 (  pg_advisory_xact_lock                               
PGNSP PGUID 12 1 0 0 f f f t f v 2 0 2278 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_xact_lock_int4 _null_ _null_ _null_ ));
+ DESCR("obtain exclusive advisory lock");
  DATA(insert OID = 2887 (  pg_advisory_lock_shared             PGNSP PGUID 12 
1 0 0 f f f t f v 2 0 2278 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_lock_shared_int4 _null_ _null_ _null_ ));
  DESCR("obtain shared advisory lock");
+ DATA(insert OID = 3076 (  pg_advisory_xact_lock_shared                PGNSP 
PGUID 12 1 0 0 f f f t f v 2 0 2278 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_xact_lock_shared_int4 _null_ _null_ _null_ ));
+ DESCR("obtain shared advisory lock");
  DATA(insert OID = 2888 (  pg_try_advisory_lock                        PGNSP 
PGUID 12 1 0 0 f f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_try_advisory_lock_int4 _null_ _null_ _null_ ));
  DESCR("obtain exclusive advisory lock if available");
+ DATA(insert OID = 3077 (  pg_try_advisory_xact_lock                   PGNSP 
PGUID 12 1 0 0 f f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_try_advisory_xact_lock_int4 _null_ _null_ _null_ ));
+ DESCR("obtain exclusive advisory lock if available");
  DATA(insert OID = 2889 (  pg_try_advisory_lock_shared PGNSP PGUID 12 1 0 0 f 
f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_try_advisory_lock_shared_int4 _null_ _null_ _null_ ));
  DESCR("obtain shared advisory lock if available");
+ DATA(insert OID = 3079 (  pg_try_advisory_xact_lock_shared    PGNSP PGUID 12 
1 0 0 f f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_try_advisory_xact_lock_shared_int4 _null_ _null_ _null_ ));
+ DESCR("obtain shared advisory lock if available");
  DATA(insert OID = 2890 (  pg_advisory_unlock                  PGNSP PGUID 12 
1 0 0 f f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_unlock_int4 _null_ _null_ _null_ ));
  DESCR("release exclusive advisory lock");
  DATA(insert OID = 2891 (  pg_advisory_unlock_shared           PGNSP PGUID 12 
1 0 0 f f f t f v 2 0 16 "23 23" _null_ _null_ _null_ _null_ 
pg_advisory_unlock_shared_int4 _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 991,1005 **** extern Datum show_all_settings(PG_FUNCTION_ARGS);
--- 991,1013 ----
  /* lockfuncs.c */
  extern Datum pg_lock_status(PG_FUNCTION_ARGS);
  extern Datum pg_advisory_lock_int8(PG_FUNCTION_ARGS);
+ extern Datum pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS);
  extern Datum pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS);
+ extern Datum pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS);
  extern Datum pg_try_advisory_lock_int8(PG_FUNCTION_ARGS);
+ extern Datum pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS);
  extern Datum pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS);
+ extern Datum pg_try_advisory_xact_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_xact_lock_int4(PG_FUNCTION_ARGS);
  extern Datum pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS);
+ extern Datum pg_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS);
  extern Datum pg_try_advisory_lock_int4(PG_FUNCTION_ARGS);
+ extern Datum pg_try_advisory_xact_lock_int4(PG_FUNCTION_ARGS);
  extern Datum pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS);
+ extern Datum pg_try_advisory_xact_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);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to