Header And Logo

PostgreSQL
| The world's most advanced open source database.

latch.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * latch.h
00004  *    Routines for interprocess latches
00005  *
00006  * A latch is a boolean variable, with operations that let processes sleep
00007  * until it is set. A latch can be set from another process, or a signal
00008  * handler within the same process.
00009  *
00010  * The latch interface is a reliable replacement for the common pattern of
00011  * using pg_usleep() or select() to wait until a signal arrives, where the
00012  * signal handler sets a flag variable. Because on some platforms an
00013  * incoming signal doesn't interrupt sleep, and even on platforms where it
00014  * does there is a race condition if the signal arrives just before
00015  * entering the sleep, the common pattern must periodically wake up and
00016  * poll the flag variable. The pselect() system call was invented to solve
00017  * this problem, but it is not portable enough. Latches are designed to
00018  * overcome these limitations, allowing you to sleep without polling and
00019  * ensuring quick response to signals from other processes.
00020  *
00021  * There are two kinds of latches: local and shared. A local latch is
00022  * initialized by InitLatch, and can only be set from the same process.
00023  * A local latch can be used to wait for a signal to arrive, by calling
00024  * SetLatch in the signal handler. A shared latch resides in shared memory,
00025  * and must be initialized at postmaster startup by InitSharedLatch. Before
00026  * a shared latch can be waited on, it must be associated with a process
00027  * with OwnLatch. Only the process owning the latch can wait on it, but any
00028  * process can set it.
00029  *
00030  * There are three basic operations on a latch:
00031  *
00032  * SetLatch     - Sets the latch
00033  * ResetLatch   - Clears the latch, allowing it to be set again
00034  * WaitLatch    - Waits for the latch to become set
00035  *
00036  * WaitLatch includes a provision for timeouts (which should be avoided
00037  * when possible, as they incur extra overhead) and a provision for
00038  * postmaster child processes to wake up immediately on postmaster death.
00039  * See unix_latch.c for detailed specifications for the exported functions.
00040  *
00041  * The correct pattern to wait for event(s) is:
00042  *
00043  * for (;;)
00044  * {
00045  *     ResetLatch();
00046  *     if (work to do)
00047  *         Do Stuff();
00048  *     WaitLatch();
00049  * }
00050  *
00051  * It's important to reset the latch *before* checking if there's work to
00052  * do. Otherwise, if someone sets the latch between the check and the
00053  * ResetLatch call, you will miss it and Wait will incorrectly block.
00054  *
00055  * To wake up the waiter, you must first set a global flag or something
00056  * else that the wait loop tests in the "if (work to do)" part, and call
00057  * SetLatch *after* that. SetLatch is designed to return quickly if the
00058  * latch is already set.
00059  *
00060  * Presently, when using a shared latch for interprocess signalling, the
00061  * flag variable(s) set by senders and inspected by the wait loop must
00062  * be protected by spinlocks or LWLocks, else it is possible to miss events
00063  * on machines with weak memory ordering (such as PPC).  This restriction
00064  * will be lifted in future by inserting suitable memory barriers into
00065  * SetLatch and ResetLatch.
00066  *
00067  * On some platforms, signals will not interrupt the latch wait primitive
00068  * by themselves.  Therefore, it is critical that any signal handler that
00069  * is meant to terminate a WaitLatch wait calls SetLatch.
00070  *
00071  * Note that use of the process latch (PGPROC.procLatch) is generally better
00072  * than an ad-hoc shared latch for signaling auxiliary processes.  This is
00073  * because generic signal handlers will call SetLatch on the process latch
00074  * only, so using any latch other than the process latch effectively precludes
00075  * use of any generic handler.
00076  *
00077  *
00078  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00079  * Portions Copyright (c) 1994, Regents of the University of California
00080  *
00081  * src/include/storage/latch.h
00082  *
00083  *-------------------------------------------------------------------------
00084  */
00085 #ifndef LATCH_H
00086 #define LATCH_H
00087 
00088 #include <signal.h>
00089 
00090 /*
00091  * Latch structure should be treated as opaque and only accessed through
00092  * the public functions. It is defined here to allow embedding Latches as
00093  * part of bigger structs.
00094  */
00095 typedef struct
00096 {
00097     sig_atomic_t is_set;
00098     bool        is_shared;
00099     int         owner_pid;
00100 #ifdef WIN32
00101     HANDLE      event;
00102 #endif
00103 } Latch;
00104 
00105 /* Bitmasks for events that may wake-up WaitLatch() clients */
00106 #define WL_LATCH_SET         (1 << 0)
00107 #define WL_SOCKET_READABLE   (1 << 1)
00108 #define WL_SOCKET_WRITEABLE  (1 << 2)
00109 #define WL_TIMEOUT           (1 << 3)
00110 #define WL_POSTMASTER_DEATH  (1 << 4)
00111 
00112 /*
00113  * prototypes for functions in latch.c
00114  */
00115 extern void InitializeLatchSupport(void);
00116 extern void InitLatch(volatile Latch *latch);
00117 extern void InitSharedLatch(volatile Latch *latch);
00118 extern void OwnLatch(volatile Latch *latch);
00119 extern void DisownLatch(volatile Latch *latch);
00120 extern int  WaitLatch(volatile Latch *latch, int wakeEvents, long timeout);
00121 extern int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents,
00122                   pgsocket sock, long timeout);
00123 extern void SetLatch(volatile Latch *latch);
00124 extern void ResetLatch(volatile Latch *latch);
00125 
00126 /* beware of memory ordering issues if you use this macro! */
00127 #define TestLatch(latch) (((volatile Latch *) (latch))->is_set)
00128 
00129 /*
00130  * Unix implementation uses SIGUSR1 for inter-process signaling.
00131  * Win32 doesn't need this.
00132  */
00133 #ifndef WIN32
00134 extern void latch_sigusr1_handler(void);
00135 #else
00136 #define latch_sigusr1_handler()  ((void) 0)
00137 #endif
00138 
00139 #endif   /* LATCH_H */