Home Explore Blog CI



postgresql

47th chunk of `doc/src/sgml/xfunc.sgml`
21bc42dca815c65b218086eb481430478d01ede173b2cdfb0000000100000fb3
 current
      backend.
     </para>

     <para>
      Unlike shared memory reserved at server startup, there is no need to
      acquire <function>AddinShmemInitLock</function> or otherwise take action
      to avoid race conditions when reserving shared memory with
      <function>GetNamedDSMSegment</function>.  This function ensures that only
      one backend allocates and initializes the segment and that all other
      backends receive a pointer to the fully allocated and initialized
      segment.
     </para>

     <para>
      A complete usage example of <function>GetNamedDSMSegment</function> can
      be found in
      <filename>src/test/modules/test_dsm_registry/test_dsm_registry.c</filename>
      in the <productname>PostgreSQL</productname> source tree.
     </para>
    </sect3>
   </sect2>

   <sect2 id="xfunc-addin-lwlocks">
    <title>LWLocks</title>

    <sect3 id="xfunc-addin-lwlocks-at-startup">
     <title>Requesting LWLocks at Startup</title>

     <para>
      Add-ins can reserve LWLocks on server startup.  As with shared memory
      reserved at server startup, the add-in's shared library must be preloaded
      by specifying it in
      <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>,
      and the shared library should register a
      <literal>shmem_request_hook</literal> in its
      <function>_PG_init</function> function.  This
      <literal>shmem_request_hook</literal> can reserve LWLocks by calling:
<programlisting>
void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
</programlisting>
      This ensures that an array of <literal>num_lwlocks</literal> LWLocks is
      available under the name <literal>tranche_name</literal>.  A pointer to
      this array can be obtained by calling:
<programlisting>
LWLockPadded *GetNamedLWLockTranche(const char *tranche_name)
</programlisting>
     </para>
    </sect3>

    <sect3 id="xfunc-addin-lwlocks-after-startup">
     <title>Requesting LWLocks After Startup</title>

     <para>
      There is another, more flexible method of obtaining LWLocks that can be
      done after server startup and outside a
      <literal>shmem_request_hook</literal>.  To do so, first allocate a
      <literal>tranche_id</literal> by calling:
<programlisting>
int LWLockNewTrancheId(void)
</programlisting>
      Next, initialize each LWLock, passing the new
      <literal>tranche_id</literal> as an argument:
<programlisting>
void LWLockInitialize(LWLock *lock, int tranche_id)
</programlisting>
      Similar to shared memory, each backend should ensure that only one
      process allocates a new <literal>tranche_id</literal> and initializes
      each new LWLock.  One way to do this is to only call these functions in
      your shared memory initialization code with the
      <function>AddinShmemInitLock</function> held exclusively.  If using
      <function>GetNamedDSMSegment</function>, calling these functions in the
      <function>init_callback</function> callback function is sufficient to
      avoid race conditions.
     </para>

     <para>
      Finally, each backend using the <literal>tranche_id</literal> should
      associate it with a <literal>tranche_name</literal> by calling:
<programlisting>
void LWLockRegisterTranche(int tranche_id, const char *tranche_name)
</programlisting>
     </para>

     <para>
      A complete usage example of <function>LWLockNewTrancheId</function>,
      <function>LWLockInitialize</function>, and
      <function>LWLockRegisterTranche</function> can be found in
      <filename>contrib/pg_prewarm/autoprewarm.c</filename> in the
      <productname>PostgreSQL</productname> source tree.
     </para>
    </sect3>
   </sect2>

   <sect2 id="xfunc-addin-wait-events">
    <title>Custom Wait Events</title>

    <para>
     Add-ins can define custom wait events under the wait event type
     <literal>Extension</literal> by calling:
<programlisting>
uint32 WaitEventExtensionNew(const

Title: LWLocks and Custom Wait Events in PostgreSQL Add-ins
Summary
Add-ins can reserve LWLocks at startup by preloading the shared library, registering a shmem_request_hook, and calling RequestNamedLWLockTranche. A pointer to the array of LWLocks can be obtained using GetNamedLWLockTranche. Alternatively, LWLocks can be obtained after startup by allocating a tranche_id with LWLockNewTrancheId, initializing each LWLock with LWLockInitialize, and associating the id with a name using LWLockRegisterTranche, ensuring only one process allocates the id and initializes the locks. Add-ins can also define custom wait events under the Extension type by calling WaitEventExtensionNew.