PostgreSQL Source Code  git master
latch.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "portability/instr_time.h"
#include "postmaster/postmaster.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/shmem.h"
#include "utils/memutils.h"
Include dependency graph for latch.c:

Go to the source code of this file.

Data Structures

struct  WaitEventSet
 

Macros

#define LatchWaitSetLatchPos   0
 

Functions

static void sendSelfPipeByte (void)
 
static void drainSelfPipe (void)
 
static int WaitEventSetWaitBlock (WaitEventSet *set, int cur_timeout, WaitEvent *occurred_events, int nevents)
 
void InitializeLatchSupport (void)
 
void InitializeLatchWaitSet (void)
 
void InitLatch (Latch *latch)
 
void InitSharedLatch (Latch *latch)
 
void OwnLatch (Latch *latch)
 
void DisownLatch (Latch *latch)
 
int WaitLatch (Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
 
int WaitLatchOrSocket (Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
 
void SetLatch (Latch *latch)
 
void ResetLatch (Latch *latch)
 
WaitEventSetCreateWaitEventSet (MemoryContext context, int nevents)
 
void FreeWaitEventSet (WaitEventSet *set)
 
int AddWaitEventToSet (WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
 
void ModifyWaitEvent (WaitEventSet *set, int pos, uint32 events, Latch *latch)
 
int WaitEventSetWait (WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
 
void latch_sigusr1_handler (void)
 

Variables

static WaitEventSetLatchWaitSet
 
static volatile sig_atomic_t waiting = false
 
static int selfpipe_readfd = -1
 
static int selfpipe_writefd = -1
 
static int selfpipe_owner_pid = 0
 

Macro Definition Documentation

◆ LatchWaitSetLatchPos

#define LatchWaitSetLatchPos   0

Definition at line 137 of file latch.c.

Referenced by InitializeLatchWaitSet(), and WaitLatch().

Function Documentation

◆ AddWaitEventToSet()

int AddWaitEventToSet ( WaitEventSet set,
uint32  events,
pgsocket  fd,
Latch latch,
void *  user_data 
)

Definition at line 808 of file latch.c.

References Assert, elog, ERROR, WaitEventSet::events, fd(), WaitEventSet::latch, MyProcPid, Latch::owner_pid, PGINVALID_SOCKET, postmaster_alive_fds, POSTMASTER_FD_WATCH, selfpipe_readfd, WaitEvent::user_data, WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_SOCKET_MASK.

Referenced by InitializeLatchWaitSet(), PgstatCollectorMain(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().

810 {
811  WaitEvent *event;
812 
813  /* not enough space */
814  Assert(set->nevents < set->nevents_space);
815 
816  if (events == WL_EXIT_ON_PM_DEATH)
817  {
818  events = WL_POSTMASTER_DEATH;
819  set->exit_on_postmaster_death = true;
820  }
821 
822  if (latch)
823  {
824  if (latch->owner_pid != MyProcPid)
825  elog(ERROR, "cannot wait on a latch owned by another process");
826  if (set->latch)
827  elog(ERROR, "cannot wait on more than one latch");
828  if ((events & WL_LATCH_SET) != WL_LATCH_SET)
829  elog(ERROR, "latch events only support being set");
830  }
831  else
832  {
833  if (events & WL_LATCH_SET)
834  elog(ERROR, "cannot wait on latch without a specified latch");
835  }
836 
837  /* waiting for socket readiness without a socket indicates a bug */
838  if (fd == PGINVALID_SOCKET && (events & WL_SOCKET_MASK))
839  elog(ERROR, "cannot wait on socket event without a socket");
840 
841  event = &set->events[set->nevents];
842  event->pos = set->nevents++;
843  event->fd = fd;
844  event->events = events;
845  event->user_data = user_data;
846 #ifdef WIN32
847  event->reset = false;
848 #endif
849 
850  if (events == WL_LATCH_SET)
851  {
852  set->latch = latch;
853  set->latch_pos = event->pos;
854 #ifndef WIN32
855  event->fd = selfpipe_readfd;
856 #endif
857  }
858  else if (events == WL_POSTMASTER_DEATH)
859  {
860 #ifndef WIN32
862 #endif
863  }
864 
865  /* perform wait primitive specific initialization, if needed */
866 #if defined(WAIT_USE_EPOLL)
867  WaitEventAdjustEpoll(set, event, EPOLL_CTL_ADD);
868 #elif defined(WAIT_USE_KQUEUE)
869  WaitEventAdjustKqueue(set, event, 0);
870 #elif defined(WAIT_USE_POLL)
871  WaitEventAdjustPoll(set, event);
872 #elif defined(WAIT_USE_WIN32)
873  WaitEventAdjustWin32(set, event);
874 #endif
875 
876  return event->pos;
877 }
int MyProcPid
Definition: globals.c:40
#define WL_SOCKET_MASK
Definition: latch.h:137
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
static int selfpipe_readfd
Definition: latch.c:144
int nevents
Definition: latch.c:85
int postmaster_alive_fds[2]
Definition: postmaster.c:573
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
#define PGINVALID_SOCKET
Definition: port.h:33
#define Assert(condition)
Definition: c.h:745
int nevents_space
Definition: latch.c:86
int owner_pid
Definition: latch.h:114
#define elog(elevel,...)
Definition: elog.h:214
Latch * latch
Definition: latch.c:100
#define WL_LATCH_SET
Definition: latch.h:124
#define POSTMASTER_FD_WATCH
Definition: postmaster.h:42
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

◆ CreateWaitEventSet()

WaitEventSet* CreateWaitEventSet ( MemoryContext  context,
int  nevents 
)

Definition at line 611 of file latch.c.

References AcquireExternalFD(), close, elog, ERROR, MAXALIGN, MemoryContextAllocZero(), WaitEventSet::nevents, pgwin32_signal_event, ReleaseExternalFD(), and StaticAssertStmt.

Referenced by InitializeLatchWaitSet(), PgstatCollectorMain(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().

612 {
613  WaitEventSet *set;
614  char *data;
615  Size sz = 0;
616 
617  /*
618  * Use MAXALIGN size/alignment to guarantee that later uses of memory are
619  * aligned correctly. E.g. epoll_event might need 8 byte alignment on some
620  * platforms, but earlier allocations like WaitEventSet and WaitEvent
621  * might not sized to guarantee that when purely using sizeof().
622  */
623  sz += MAXALIGN(sizeof(WaitEventSet));
624  sz += MAXALIGN(sizeof(WaitEvent) * nevents);
625 
626 #if defined(WAIT_USE_EPOLL)
627  sz += MAXALIGN(sizeof(struct epoll_event) * nevents);
628 #elif defined(WAIT_USE_KQUEUE)
629  sz += MAXALIGN(sizeof(struct kevent) * nevents);
630 #elif defined(WAIT_USE_POLL)
631  sz += MAXALIGN(sizeof(struct pollfd) * nevents);
632 #elif defined(WAIT_USE_WIN32)
633  /* need space for the pgwin32_signal_event */
634  sz += MAXALIGN(sizeof(HANDLE) * (nevents + 1));
635 #endif
636 
637  data = (char *) MemoryContextAllocZero(context, sz);
638 
639  set = (WaitEventSet *) data;
640  data += MAXALIGN(sizeof(WaitEventSet));
641 
642  set->events = (WaitEvent *) data;
643  data += MAXALIGN(sizeof(WaitEvent) * nevents);
644 
645 #if defined(WAIT_USE_EPOLL)
646  set->epoll_ret_events = (struct epoll_event *) data;
647  data += MAXALIGN(sizeof(struct epoll_event) * nevents);
648 #elif defined(WAIT_USE_KQUEUE)
649  set->kqueue_ret_events = (struct kevent *) data;
650  data += MAXALIGN(sizeof(struct kevent) * nevents);
651 #elif defined(WAIT_USE_POLL)
652  set->pollfds = (struct pollfd *) data;
653  data += MAXALIGN(sizeof(struct pollfd) * nevents);
654 #elif defined(WAIT_USE_WIN32)
655  set->handles = (HANDLE) data;
656  data += MAXALIGN(sizeof(HANDLE) * nevents);
657 #endif
658 
659  set->latch = NULL;
660  set->nevents_space = nevents;
661  set->exit_on_postmaster_death = false;
662 
663 #if defined(WAIT_USE_EPOLL)
664  if (!AcquireExternalFD())
665  {
666  /* treat this as though epoll_create1 itself returned EMFILE */
667  elog(ERROR, "epoll_create1 failed: %m");
668  }
669 #ifdef EPOLL_CLOEXEC
670  set->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
671  if (set->epoll_fd < 0)
672  {
674  elog(ERROR, "epoll_create1 failed: %m");
675  }
676 #else
677  /* cope with ancient glibc lacking epoll_create1 (e.g., RHEL5) */
678  set->epoll_fd = epoll_create(nevents);
679  if (set->epoll_fd < 0)
680  {
682  elog(ERROR, "epoll_create failed: %m");
683  }
684  if (fcntl(set->epoll_fd, F_SETFD, FD_CLOEXEC) == -1)
685  {
686  int save_errno = errno;
687 
688  close(set->epoll_fd);
690  errno = save_errno;
691  elog(ERROR, "fcntl(F_SETFD) failed on epoll descriptor: %m");
692  }
693 #endif /* EPOLL_CLOEXEC */
694 #elif defined(WAIT_USE_KQUEUE)
695  if (!AcquireExternalFD())
696  {
697  /* treat this as though kqueue itself returned EMFILE */
698  elog(ERROR, "kqueue failed: %m");
699  }
700  set->kqueue_fd = kqueue();
701  if (set->kqueue_fd < 0)
702  {
704  elog(ERROR, "kqueue failed: %m");
705  }
706  if (fcntl(set->kqueue_fd, F_SETFD, FD_CLOEXEC) == -1)
707  {
708  int save_errno = errno;
709 
710  close(set->kqueue_fd);
712  errno = save_errno;
713  elog(ERROR, "fcntl(F_SETFD) failed on kqueue descriptor: %m");
714  }
715  set->report_postmaster_not_running = false;
716 #elif defined(WAIT_USE_WIN32)
717 
718  /*
719  * To handle signals while waiting, we need to add a win32 specific event.
720  * We accounted for the additional event at the top of this routine. See
721  * port/win32/signal.c for more details.
722  *
723  * Note: pgwin32_signal_event should be first to ensure that it will be
724  * reported when multiple events are set. We want to guarantee that
725  * pending signals are serviced.
726  */
727  set->handles[0] = pgwin32_signal_event;
728  StaticAssertStmt(WSA_INVALID_EVENT == NULL, "");
729 #endif
730 
731  return set;
732 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:859
HANDLE pgwin32_signal_event
Definition: signal.c:27
#define ERROR
Definition: elog.h:43
bool AcquireExternalFD(void)
Definition: fd.c:1048
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:840
size_t Size
Definition: c.h:473
#define MAXALIGN(LEN)
Definition: c.h:698
void ReleaseExternalFD(void)
Definition: fd.c:1101
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12

◆ DisownLatch()

void DisownLatch ( Latch latch)

Definition at line 362 of file latch.c.

References Assert, Latch::is_shared, MyProcPid, and Latch::owner_pid.

Referenced by AuxiliaryProcKill(), ProcKill(), and StartupXLOG().

363 {
364  Assert(latch->is_shared);
365  Assert(latch->owner_pid == MyProcPid);
366 
367  latch->owner_pid = 0;
368 }
int MyProcPid
Definition: globals.c:40
bool is_shared
Definition: latch.h:113
#define Assert(condition)
Definition: c.h:745
int owner_pid
Definition: latch.h:114

◆ drainSelfPipe()

static void drainSelfPipe ( void  )
static

Definition at line 1963 of file latch.c.

References buf, EAGAIN, EINTR, elog, ERROR, EWOULDBLOCK, read, selfpipe_readfd, and waiting.

Referenced by WaitEventSetWait().

1964 {
1965  /*
1966  * There shouldn't normally be more than one byte in the pipe, or maybe a
1967  * few bytes if multiple processes run SetLatch at the same instant.
1968  */
1969  char buf[16];
1970  int rc;
1971 
1972  for (;;)
1973  {
1974  rc = read(selfpipe_readfd, buf, sizeof(buf));
1975  if (rc < 0)
1976  {
1977  if (errno == EAGAIN || errno == EWOULDBLOCK)
1978  break; /* the pipe is empty */
1979  else if (errno == EINTR)
1980  continue; /* retry */
1981  else
1982  {
1983  waiting = false;
1984  elog(ERROR, "read() on self-pipe failed: %m");
1985  }
1986  }
1987  else if (rc == 0)
1988  {
1989  waiting = false;
1990  elog(ERROR, "unexpected EOF on self-pipe");
1991  }
1992  else if (rc < sizeof(buf))
1993  {
1994  /* we successfully drained the pipe; no need to read() again */
1995  break;
1996  }
1997  /* else buffer wasn't big enough, so read again */
1998  }
1999 }
#define EAGAIN
Definition: win32_port.h:321
#define ERROR
Definition: elog.h:43
static int selfpipe_readfd
Definition: latch.c:144
static char * buf
Definition: pg_test_fsync.c:67
#define elog(elevel,...)
Definition: elog.h:214
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323
static volatile sig_atomic_t waiting
Definition: latch.c:141
#define read(a, b, c)
Definition: win32.h:13

◆ FreeWaitEventSet()

void FreeWaitEventSet ( WaitEventSet set)

Definition at line 744 of file latch.c.

References close, WaitEvent::events, WaitEvent::fd, pfree(), WaitEvent::pos, ReleaseExternalFD(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by PgstatCollectorMain(), and WaitLatchOrSocket().

745 {
746 #if defined(WAIT_USE_EPOLL)
747  close(set->epoll_fd);
749 #elif defined(WAIT_USE_KQUEUE)
750  close(set->kqueue_fd);
752 #elif defined(WAIT_USE_WIN32)
753  WaitEvent *cur_event;
754 
755  for (cur_event = set->events;
756  cur_event < (set->events + set->nevents);
757  cur_event++)
758  {
759  if (cur_event->events & WL_LATCH_SET)
760  {
761  /* uses the latch's HANDLE */
762  }
763  else if (cur_event->events & WL_POSTMASTER_DEATH)
764  {
765  /* uses PostmasterHandle */
766  }
767  else
768  {
769  /* Clean up the event object we created for the socket */
770  WSAEventSelect(cur_event->fd, NULL, 0);
771  WSACloseEvent(set->handles[cur_event->pos + 1]);
772  }
773  }
774 #endif
775 
776  pfree(set);
777 }
pgsocket fd
Definition: latch.h:145
int pos
Definition: latch.h:143
void pfree(void *pointer)
Definition: mcxt.c:1057
uint32 events
Definition: latch.h:144
int nevents
Definition: latch.c:85
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
WaitEvent * events
Definition: latch.c:92
void ReleaseExternalFD(void)
Definition: fd.c:1101
#define close(a)
Definition: win32.h:12
#define WL_LATCH_SET
Definition: latch.h:124

◆ InitializeLatchSupport()

void InitializeLatchSupport ( void  )

Definition at line 175 of file latch.c.

References Assert, close, elog, FATAL, IsUnderPostmaster, MyProcPid, ReleaseExternalFD(), ReserveExternalFD(), selfpipe_owner_pid, selfpipe_readfd, and selfpipe_writefd.

Referenced by InitPostmasterChild(), and InitStandaloneProcess().

176 {
177 #ifndef WIN32
178  int pipefd[2];
179 
180  if (IsUnderPostmaster)
181  {
182  /*
183  * We might have inherited connections to a self-pipe created by the
184  * postmaster. It's critical that child processes create their own
185  * self-pipes, of course, and we really want them to close the
186  * inherited FDs for safety's sake.
187  */
188  if (selfpipe_owner_pid != 0)
189  {
190  /* Assert we go through here but once in a child process */
192  /* Release postmaster's pipe FDs; ignore any error */
193  (void) close(selfpipe_readfd);
194  (void) close(selfpipe_writefd);
195  /* Clean up, just for safety's sake; we'll set these below */
197  selfpipe_owner_pid = 0;
198  /* Keep fd.c's accounting straight */
201  }
202  else
203  {
204  /*
205  * Postmaster didn't create a self-pipe ... or else we're in an
206  * EXEC_BACKEND build, in which case it doesn't matter since the
207  * postmaster's pipe FDs were closed by the action of FD_CLOEXEC.
208  * fd.c won't have state to clean up, either.
209  */
210  Assert(selfpipe_readfd == -1);
211  }
212  }
213  else
214  {
215  /* In postmaster or standalone backend, assert we do this but once */
216  Assert(selfpipe_readfd == -1);
218  }
219 
220  /*
221  * Set up the self-pipe that allows a signal handler to wake up the
222  * poll()/epoll_wait() in WaitLatch. Make the write-end non-blocking, so
223  * that SetLatch won't block if the event has already been set many times
224  * filling the kernel buffer. Make the read-end non-blocking too, so that
225  * we can easily clear the pipe by reading until EAGAIN or EWOULDBLOCK.
226  * Also, make both FDs close-on-exec, since we surely do not want any
227  * child processes messing with them.
228  */
229  if (pipe(pipefd) < 0)
230  elog(FATAL, "pipe() failed: %m");
231  if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1)
232  elog(FATAL, "fcntl(F_SETFL) failed on read-end of self-pipe: %m");
233  if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1)
234  elog(FATAL, "fcntl(F_SETFL) failed on write-end of self-pipe: %m");
235  if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)
236  elog(FATAL, "fcntl(F_SETFD) failed on read-end of self-pipe: %m");
237  if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1)
238  elog(FATAL, "fcntl(F_SETFD) failed on write-end of self-pipe: %m");
239 
240  selfpipe_readfd = pipefd[0];
241  selfpipe_writefd = pipefd[1];
243 
244  /* Tell fd.c about these two long-lived FDs */
247 #else
248  /* currently, nothing to do here for Windows */
249 #endif
250 }
int MyProcPid
Definition: globals.c:40
static int selfpipe_writefd
Definition: latch.c:145
#define FATAL
Definition: elog.h:52
static int selfpipe_readfd
Definition: latch.c:144
void ReserveExternalFD(void)
Definition: fd.c:1083
bool IsUnderPostmaster
Definition: globals.c:109
#define Assert(condition)
Definition: c.h:745
void ReleaseExternalFD(void)
Definition: fd.c:1101
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12
static int selfpipe_owner_pid
Definition: latch.c:148

◆ InitializeLatchWaitSet()

void InitializeLatchWaitSet ( void  )

Definition at line 253 of file latch.c.

References AddWaitEventToSet(), Assert, CreateWaitEventSet(), IsUnderPostmaster, WaitEventSet::latch_pos, LatchWaitSetLatchPos, MyLatch, PG_USED_FOR_ASSERTS_ONLY, PGINVALID_SOCKET, TopMemoryContext, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by InitPostmasterChild(), and InitStandaloneProcess().

254 {
255  int latch_pos PG_USED_FOR_ASSERTS_ONLY;
256 
257  Assert(LatchWaitSet == NULL);
258 
259  /* Set up the WaitEventSet used by WaitLatch(). */
262  MyLatch, NULL);
263  if (IsUnderPostmaster)
265  PGINVALID_SOCKET, NULL, NULL);
266 
267  Assert(latch_pos == LatchWaitSetLatchPos);
268 }
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: latch.c:808
WaitEventSet * CreateWaitEventSet(MemoryContext context, int nevents)
Definition: latch.c:611
#define LatchWaitSetLatchPos
Definition: latch.c:137
bool IsUnderPostmaster
Definition: globals.c:109
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define PGINVALID_SOCKET
Definition: port.h:33
#define Assert(condition)
Definition: c.h:745
struct Latch * MyLatch
Definition: globals.c:54
static WaitEventSet * LatchWaitSet
Definition: latch.c:134
#define WL_LATCH_SET
Definition: latch.h:124
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:121

◆ InitLatch()

void InitLatch ( Latch latch)

Definition at line 274 of file latch.c.

References Assert, elog, ERROR, Latch::is_set, Latch::is_shared, MyProcPid, Latch::owner_pid, selfpipe_owner_pid, and selfpipe_readfd.

Referenced by InitPostmasterChild(), and InitStandaloneProcess().

275 {
276  latch->is_set = false;
277  latch->owner_pid = MyProcPid;
278  latch->is_shared = false;
279 
280 #ifndef WIN32
281  /* Assert InitializeLatchSupport has been called in this process */
283 #else
284  latch->event = CreateEvent(NULL, TRUE, FALSE, NULL);
285  if (latch->event == NULL)
286  elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
287 #endif /* WIN32 */
288 }
int MyProcPid
Definition: globals.c:40
bool is_shared
Definition: latch.h:113
#define ERROR
Definition: elog.h:43
static int selfpipe_readfd
Definition: latch.c:144
#define Assert(condition)
Definition: c.h:745
int owner_pid
Definition: latch.h:114
sig_atomic_t is_set
Definition: latch.h:112
#define elog(elevel,...)
Definition: elog.h:214
static int selfpipe_owner_pid
Definition: latch.c:148

◆ InitSharedLatch()

void InitSharedLatch ( Latch latch)

Definition at line 306 of file latch.c.

References elog, ERROR, Latch::is_set, Latch::is_shared, and Latch::owner_pid.

Referenced by InitProcGlobal(), and XLOGShmemInit().

307 {
308 #ifdef WIN32
309  SECURITY_ATTRIBUTES sa;
310 
311  /*
312  * Set up security attributes to specify that the events are inherited.
313  */
314  ZeroMemory(&sa, sizeof(sa));
315  sa.nLength = sizeof(sa);
316  sa.bInheritHandle = TRUE;
317 
318  latch->event = CreateEvent(&sa, TRUE, FALSE, NULL);
319  if (latch->event == NULL)
320  elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
321 #endif
322 
323  latch->is_set = false;
324  latch->owner_pid = 0;
325  latch->is_shared = true;
326 }
bool is_shared
Definition: latch.h:113
#define ERROR
Definition: elog.h:43
int owner_pid
Definition: latch.h:114
sig_atomic_t is_set
Definition: latch.h:112
#define elog(elevel,...)
Definition: elog.h:214

◆ latch_sigusr1_handler()

void latch_sigusr1_handler ( void  )

Definition at line 1914 of file latch.c.

References sendSelfPipeByte(), and waiting.

Referenced by bgworker_sigusr1_handler(), and procsignal_sigusr1_handler().

1915 {
1916  if (waiting)
1917  sendSelfPipeByte();
1918 }
static void sendSelfPipeByte(void)
Definition: latch.c:1924
static volatile sig_atomic_t waiting
Definition: latch.c:141

◆ ModifyWaitEvent()

void ModifyWaitEvent ( WaitEventSet set,
int  pos,
uint32  events,
Latch latch 
)

Definition at line 887 of file latch.c.

References generate_unaccent_rules::action, Assert, elog, ereport, errcode_for_socket_access(), errmsg(), ERROR, WaitEventSet::events, WaitEvent::events, WaitEvent::fd, WaitEventSet::latch, WaitEventSet::nevents, PGINVALID_SOCKET, PostmasterIsAlive, PostmasterPid, WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_SOCKET_CONNECTED, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_read(), secure_write(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), and WaitLatch().

888 {
889  WaitEvent *event;
890 #if defined(WAIT_USE_KQUEUE)
891  int old_events;
892 #endif
893 
894  Assert(pos < set->nevents);
895 
896  event = &set->events[pos];
897 #if defined(WAIT_USE_KQUEUE)
898  old_events = event->events;
899 #endif
900 
901  /*
902  * If neither the event mask nor the associated latch changes, return
903  * early. That's an important optimization for some sockets, where
904  * ModifyWaitEvent is frequently used to switch from waiting for reads to
905  * waiting on writes.
906  */
907  if (events == event->events &&
908  (!(event->events & WL_LATCH_SET) || set->latch == latch))
909  return;
910 
911  if (event->events & WL_LATCH_SET &&
912  events != event->events)
913  {
914  elog(ERROR, "cannot modify latch event");
915  }
916 
917  if (event->events & WL_POSTMASTER_DEATH)
918  {
919  elog(ERROR, "cannot modify postmaster death event");
920  }
921 
922  /* FIXME: validate event mask */
923  event->events = events;
924 
925  if (events == WL_LATCH_SET)
926  {
927  set->latch = latch;
928  }
929 
930 #if defined(WAIT_USE_EPOLL)
931  WaitEventAdjustEpoll(set, event, EPOLL_CTL_MOD);
932 #elif defined(WAIT_USE_KQUEUE)
933  WaitEventAdjustKqueue(set, event, old_events);
934 #elif defined(WAIT_USE_POLL)
935  WaitEventAdjustPoll(set, event);
936 #elif defined(WAIT_USE_WIN32)
937  WaitEventAdjustWin32(set, event);
938 #endif
939 }
#define ERROR
Definition: elog.h:43
uint32 events
Definition: latch.h:144
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
#define Assert(condition)
Definition: c.h:745
#define elog(elevel,...)
Definition: elog.h:214
Latch * latch
Definition: latch.c:100
#define WL_LATCH_SET
Definition: latch.h:124

◆ OwnLatch()

void OwnLatch ( Latch latch)

Definition at line 342 of file latch.c.

References Assert, elog, ERROR, Latch::is_shared, MyProcPid, Latch::owner_pid, selfpipe_owner_pid, and selfpipe_readfd.

Referenced by InitAuxiliaryProcess(), InitProcess(), and StartupXLOG().

343 {
344  /* Sanity checks */
345  Assert(latch->is_shared);
346 
347 #ifndef WIN32
348  /* Assert InitializeLatchSupport has been called in this process */
350 #endif
351 
352  if (latch->owner_pid != 0)
353  elog(ERROR, "latch already owned");
354 
355  latch->owner_pid = MyProcPid;
356 }
int MyProcPid
Definition: globals.c:40
bool is_shared
Definition: latch.h:113
#define ERROR
Definition: elog.h:43
static int selfpipe_readfd
Definition: latch.c:144
#define Assert(condition)
Definition: c.h:745
int owner_pid
Definition: latch.h:114
#define elog(elevel,...)
Definition: elog.h:214
static int selfpipe_owner_pid
Definition: latch.c:148

◆ ResetLatch()

void ResetLatch ( Latch latch)

Definition at line 588 of file latch.c.

References Assert, Latch::is_set, MyProcPid, Latch::owner_pid, and pg_memory_barrier.

Referenced by ApplyLauncherMain(), autoprewarm_main(), AutoVacLauncherMain(), BackgroundWriterMain(), CheckpointerMain(), ConditionVariableTimedSleep(), copy_read_data(), gather_readnext(), initialize_worker_spi(), libpqrcv_connect(), libpqrcv_PQgetResult(), logicalrep_worker_stop(), LogicalRepApplyLoop(), mq_putmessage(), pg_promote(), pg_sleep(), pgarch_MainLoop(), pgfdw_get_cleanup_result(), pgfdw_get_result(), PgstatCollectorMain(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), secure_read(), secure_write(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), SyncRepWaitForLSN(), SysLoggerMain(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForProcSignalBarrier(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), WalReceiverMain(), WalSndLoop(), WalSndWaitForWal(), WalSndWriteData(), and WalWriterMain().

589 {
590  /* Only the owner should reset the latch */
591  Assert(latch->owner_pid == MyProcPid);
592 
593  latch->is_set = false;
594 
595  /*
596  * Ensure that the write to is_set gets flushed to main memory before we
597  * examine any flag variables. Otherwise a concurrent SetLatch might
598  * falsely conclude that it needn't signal us, even though we have missed
599  * seeing some flag updates that SetLatch was supposed to inform us of.
600  */
602 }
int MyProcPid
Definition: globals.c:40
#define pg_memory_barrier()
Definition: atomics.h:145
#define Assert(condition)
Definition: c.h:745
int owner_pid
Definition: latch.h:114
sig_atomic_t is_set
Definition: latch.h:112

◆ sendSelfPipeByte()

static void sendSelfPipeByte ( void  )
static

Definition at line 1924 of file latch.c.

References EAGAIN, EINTR, EWOULDBLOCK, selfpipe_writefd, and write.

Referenced by latch_sigusr1_handler(), and SetLatch().

1925 {
1926  int rc;
1927  char dummy = 0;
1928 
1929 retry:
1930  rc = write(selfpipe_writefd, &dummy, 1);
1931  if (rc < 0)
1932  {
1933  /* If interrupted by signal, just retry */
1934  if (errno == EINTR)
1935  goto retry;
1936 
1937  /*
1938  * If the pipe is full, we don't need to retry, the data that's there
1939  * already is enough to wake up WaitLatch.
1940  */
1941  if (errno == EAGAIN || errno == EWOULDBLOCK)
1942  return;
1943 
1944  /*
1945  * Oops, the write() failed for some other reason. We might be in a
1946  * signal handler, so it's not safe to elog(). We have no choice but
1947  * silently ignore the error.
1948  */
1949  return;
1950  }
1951 }
static int selfpipe_writefd
Definition: latch.c:145
#define EAGAIN
Definition: win32_port.h:321
#define write(a, b, c)
Definition: win32.h:14
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323

◆ SetLatch()

void SetLatch ( Latch latch)

Definition at line 505 of file latch.c.

References Latch::is_set, kill, MyProcPid, Latch::owner_pid, pg_memory_barrier, sendSelfPipeByte(), SIGUSR1, and waiting.

Referenced by apw_sighup_handler(), apw_sigterm_handler(), avl_sigusr2_handler(), CheckDeadLockAlert(), ConditionVariableBroadcast(), ConditionVariableSignal(), die(), ForwardSyncRequest(), handle_sig_alarm(), handle_sigterm(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), HandleParallelMessageInterrupt(), IdleInTransactionSessionTimeoutHandler(), logicalrep_worker_wakeup_ptr(), pgarch_waken(), pgarch_waken_stop(), ProcessClientReadInterrupt(), ProcessClientWriteInterrupt(), ProcSendSignal(), procsignal_sigusr1_handler(), ProcWakeup(), RecoveryConflictInterrupt(), ReqCheckpointHandler(), RequestXLogStreaming(), shm_mq_detach_internal(), shm_mq_inc_bytes_read(), shm_mq_send_bytes(), shm_mq_sendv(), shm_mq_set_receiver(), shm_mq_set_sender(), sigHupHandler(), SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), sigUsr1Handler(), StatementCancelHandler(), StrategyGetBuffer(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepWakeQueue(), test_shm_mq_main(), WakeupRecovery(), WalRcvForceReply(), WalRcvShutdownHandler(), WalSndLastCycleHandler(), WalSndWaitForWal(), WalSndWakeup(), WalSndWriteData(), worker_spi_sighup(), worker_spi_sigterm(), write_syslogger_file(), and XLogSetAsyncXactLSN().

506 {
507 #ifndef WIN32
508  pid_t owner_pid;
509 #else
510  HANDLE handle;
511 #endif
512 
513  /*
514  * The memory barrier has to be placed here to ensure that any flag
515  * variables possibly changed by this process have been flushed to main
516  * memory, before we check/set is_set.
517  */
519 
520  /* Quick exit if already set */
521  if (latch->is_set)
522  return;
523 
524  latch->is_set = true;
525 
526 #ifndef WIN32
527 
528  /*
529  * See if anyone's waiting for the latch. It can be the current process if
530  * we're in a signal handler. We use the self-pipe to wake up the
531  * poll()/epoll_wait() in that case. If it's another process, send a
532  * signal.
533  *
534  * Fetch owner_pid only once, in case the latch is concurrently getting
535  * owned or disowned. XXX: This assumes that pid_t is atomic, which isn't
536  * guaranteed to be true! In practice, the effective range of pid_t fits
537  * in a 32 bit integer, and so should be atomic. In the worst case, we
538  * might end up signaling the wrong process. Even then, you're very
539  * unlucky if a process with that bogus pid exists and belongs to
540  * Postgres; and PG database processes should handle excess SIGUSR1
541  * interrupts without a problem anyhow.
542  *
543  * Another sort of race condition that's possible here is for a new
544  * process to own the latch immediately after we look, so we don't signal
545  * it. This is okay so long as all callers of ResetLatch/WaitLatch follow
546  * the standard coding convention of waiting at the bottom of their loops,
547  * not the top, so that they'll correctly process latch-setting events
548  * that happen before they enter the loop.
549  */
550  owner_pid = latch->owner_pid;
551  if (owner_pid == 0)
552  return;
553  else if (owner_pid == MyProcPid)
554  {
555  if (waiting)
557  }
558  else
559  kill(owner_pid, SIGUSR1);
560 #else
561 
562  /*
563  * See if anyone's waiting for the latch. It can be the current process if
564  * we're in a signal handler.
565  *
566  * Use a local variable here just in case somebody changes the event field
567  * concurrently (which really should not happen).
568  */
569  handle = latch->event;
570  if (handle)
571  {
572  SetEvent(handle);
573 
574  /*
575  * Note that we silently ignore any errors. We might be in a signal
576  * handler or other critical path where it's not safe to call elog().
577  */
578  }
579 #endif
580 
581 }
int MyProcPid
Definition: globals.c:40
#define SIGUSR1
Definition: win32_port.h:165
#define kill(pid, sig)
Definition: win32_port.h:426
static void sendSelfPipeByte(void)
Definition: latch.c:1924
#define pg_memory_barrier()
Definition: atomics.h:145
int owner_pid
Definition: latch.h:114
sig_atomic_t is_set
Definition: latch.h:112
static volatile sig_atomic_t waiting
Definition: latch.c:141

◆ WaitEventSetWait()

int WaitEventSetWait ( WaitEventSet set,
long  timeout,
WaitEvent occurred_events,
int  nevents,
uint32  wait_event_info 
)

Definition at line 1215 of file latch.c.

References Assert, buf, drainSelfPipe(), EINTR, elog, ereport, errcode_for_socket_access(), errmsg(), ERROR, WaitEvent::events, WaitEvent::fd, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, WaitEventSet::nevents, PGINVALID_SOCKET, pgstat_report_wait_end(), pgstat_report_wait_start(), pgwin32_dispatch_queued_signals(), WaitEvent::pos, PostmasterIsAliveInternal(), proc_exit(), start_time, unlikely, WaitEvent::user_data, WaitEventSetWaitBlock(), waiting, WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_SOCKET_CONNECTED, WL_SOCKET_MASK, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by PgstatCollectorMain(), secure_read(), secure_write(), SysLoggerMain(), WaitLatch(), and WaitLatchOrSocket().

1218 {
1219  int returned_events = 0;
1221  instr_time cur_time;
1222  long cur_timeout = -1;
1223 
1224  Assert(nevents > 0);
1225 
1226  /*
1227  * Initialize timeout if requested. We must record the current time so
1228  * that we can determine the remaining timeout if interrupted.
1229  */
1230  if (timeout >= 0)
1231  {
1232  INSTR_TIME_SET_CURRENT(start_time);
1233  Assert(timeout >= 0 && timeout <= INT_MAX);
1234  cur_timeout = timeout;
1235  }
1236 
1237  pgstat_report_wait_start(wait_event_info);
1238 
1239 #ifndef WIN32
1240  waiting = true;
1241 #else
1242  /* Ensure that signals are serviced even if latch is already set */
1244 #endif
1245  while (returned_events == 0)
1246  {
1247  int rc;
1248 
1249  /*
1250  * Check if the latch is set already. If so, leave the loop
1251  * immediately, avoid blocking again. We don't attempt to report any
1252  * other events that might also be satisfied.
1253  *
1254  * If someone sets the latch between this and the
1255  * WaitEventSetWaitBlock() below, the setter will write a byte to the
1256  * pipe (or signal us and the signal handler will do that), and the
1257  * readiness routine will return immediately.
1258  *
1259  * On unix, If there's a pending byte in the self pipe, we'll notice
1260  * whenever blocking. Only clearing the pipe in that case avoids
1261  * having to drain it every time WaitLatchOrSocket() is used. Should
1262  * the pipe-buffer fill up we're still ok, because the pipe is in
1263  * nonblocking mode. It's unlikely for that to happen, because the
1264  * self pipe isn't filled unless we're blocking (waiting = true), or
1265  * from inside a signal handler in latch_sigusr1_handler().
1266  *
1267  * On windows, we'll also notice if there's a pending event for the
1268  * latch when blocking, but there's no danger of anything filling up,
1269  * as "Setting an event that is already set has no effect.".
1270  *
1271  * Note: we assume that the kernel calls involved in latch management
1272  * will provide adequate synchronization on machines with weak memory
1273  * ordering, so that we cannot miss seeing is_set if a notification
1274  * has already been queued.
1275  */
1276  if (set->latch && set->latch->is_set)
1277  {
1278  occurred_events->fd = PGINVALID_SOCKET;
1279  occurred_events->pos = set->latch_pos;
1280  occurred_events->user_data =
1281  set->events[set->latch_pos].user_data;
1282  occurred_events->events = WL_LATCH_SET;
1283  occurred_events++;
1284  returned_events++;
1285 
1286  break;
1287  }
1288 
1289  /*
1290  * Wait for events using the readiness primitive chosen at the top of
1291  * this file. If -1 is returned, a timeout has occurred, if 0 we have
1292  * to retry, everything >= 1 is the number of returned events.
1293  */
1294  rc = WaitEventSetWaitBlock(set, cur_timeout,
1295  occurred_events, nevents);
1296 
1297  if (rc == -1)
1298  break; /* timeout occurred */
1299  else
1300  returned_events = rc;
1301 
1302  /* If we're not done, update cur_timeout for next iteration */
1303  if (returned_events == 0 && timeout >= 0)
1304  {
1305  INSTR_TIME_SET_CURRENT(cur_time);
1306  INSTR_TIME_SUBTRACT(cur_time, start_time);
1307  cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time);
1308  if (cur_timeout <= 0)
1309  break;
1310  }
1311  }
1312 #ifndef WIN32
1313  waiting = false;
1314 #endif
1315 
1317 
1318  return returned_events;
1319 }
pgsocket fd
Definition: latch.h:145
int pos
Definition: latch.h:143
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
struct timeval instr_time
Definition: instr_time.h:150
static time_t start_time
Definition: pg_ctl.c:99
void pgwin32_dispatch_queued_signals(void)
Definition: signal.c:108
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
uint32 events
Definition: latch.h:144
static int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, WaitEvent *occurred_events, int nevents)
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
#define PGINVALID_SOCKET
Definition: port.h:33
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
void * user_data
Definition: latch.h:146
sig_atomic_t is_set
Definition: latch.h:112
Latch * latch
Definition: latch.c:100
#define WL_LATCH_SET
Definition: latch.h:124
static volatile sig_atomic_t waiting
Definition: latch.c:141

◆ WaitEventSetWaitBlock()

static int WaitEventSetWaitBlock ( WaitEventSet set,
int  cur_timeout,
WaitEvent occurred_events,
int  nevents 
)
inlinestatic

Referenced by WaitEventSetWait().

◆ WaitLatch()

int WaitLatch ( Latch latch,
int  wakeEvents,
long  timeout,
uint32  wait_event_info 
)

Definition at line 390 of file latch.c.

References Assert, WaitEventSet::exit_on_postmaster_death, IsUnderPostmaster, LatchWaitSetLatchPos, ModifyWaitEvent(), WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by ApplyLauncherMain(), autoprewarm_main(), AutoVacLauncherMain(), BackgroundWriterMain(), CheckpointerMain(), ConditionVariableTimedSleep(), gather_readnext(), initialize_worker_spi(), logicalrep_worker_stop(), mq_putmessage(), pg_promote(), pg_sleep(), pgarch_MainLoop(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), SyncRepWaitForLSN(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForProcSignalBarrier(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), and WalWriterMain().

392 {
393  WaitEvent event;
394 
395  /* Postmaster-managed callers must handle postmaster death somehow. */
397  (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
398  (wakeEvents & WL_POSTMASTER_DEATH));
399 
400  /*
401  * Some callers may have a latch other than MyLatch, or no latch at all,
402  * or want to handle postmaster death differently. It's cheap to assign
403  * those, so just do it every time.
404  */
405  if (!(wakeEvents & WL_LATCH_SET))
406  latch = NULL;
407  ModifyWaitEvent(LatchWaitSet, LatchWaitSetLatchPos, WL_LATCH_SET, latch);
409  ((wakeEvents & WL_EXIT_ON_PM_DEATH) != 0);
410 
412  (wakeEvents & WL_TIMEOUT) ? timeout : -1,
413  &event, 1,
414  wait_event_info) == 0)
415  return WL_TIMEOUT;
416  else
417  return event.events;
418 }
#define WL_TIMEOUT
Definition: latch.h:127
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: latch.c:887
#define LatchWaitSetLatchPos
Definition: latch.c:137
bool exit_on_postmaster_death
Definition: latch.c:108
bool IsUnderPostmaster
Definition: globals.c:109
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
#define Assert(condition)
Definition: c.h:745
static WaitEventSet * LatchWaitSet
Definition: latch.c:134
#define WL_LATCH_SET
Definition: latch.h:124
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:1215

◆ WaitLatchOrSocket()

int WaitLatchOrSocket ( Latch latch,
int  wakeEvents,
pgsocket  sock,
long  timeout,
uint32  wait_event_info 
)

Definition at line 438 of file latch.c.

References AddWaitEventToSet(), Assert, CreateWaitEventSet(), CurrentMemoryContext, FreeWaitEventSet(), IsUnderPostmaster, PGINVALID_SOCKET, WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_SOCKET_MASK, and WL_TIMEOUT.

Referenced by be_tls_open_server(), copy_read_data(), libpqrcv_connect(), libpqrcv_PQgetResult(), LogicalRepApplyLoop(), pgfdw_get_cleanup_result(), pgfdw_get_result(), read_or_wait(), secure_open_gssapi(), WalReceiverMain(), WalSndLoop(), WalSndWaitForWal(), and WalSndWriteData().

440 {
441  int ret = 0;
442  int rc;
443  WaitEvent event;
445 
446  if (wakeEvents & WL_TIMEOUT)
447  Assert(timeout >= 0);
448  else
449  timeout = -1;
450 
451  if (wakeEvents & WL_LATCH_SET)
452  AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
453  latch, NULL);
454 
455  /* Postmaster-managed callers must handle postmaster death somehow. */
457  (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
458  (wakeEvents & WL_POSTMASTER_DEATH));
459 
460  if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
461  AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
462  NULL, NULL);
463 
464  if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
465  AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
466  NULL, NULL);
467 
468  if (wakeEvents & WL_SOCKET_MASK)
469  {
470  int ev;
471 
472  ev = wakeEvents & WL_SOCKET_MASK;
473  AddWaitEventToSet(set, ev, sock, NULL, NULL);
474  }
475 
476  rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
477 
478  if (rc == 0)
479  ret |= WL_TIMEOUT;
480  else
481  {
482  ret |= event.events & (WL_LATCH_SET |
483  WL_POSTMASTER_DEATH |
485  }
486 
487  FreeWaitEventSet(set);
488 
489  return ret;
490 }
void FreeWaitEventSet(WaitEventSet *set)
Definition: latch.c:744
#define WL_TIMEOUT
Definition: latch.h:127
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: latch.c:808
#define WL_SOCKET_MASK
Definition: latch.h:137
WaitEventSet * CreateWaitEventSet(MemoryContext context, int nevents)
Definition: latch.c:611
bool IsUnderPostmaster
Definition: globals.c:109
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
#define PGINVALID_SOCKET
Definition: port.h:33
#define Assert(condition)
Definition: c.h:745
#define WL_LATCH_SET
Definition: latch.h:124
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:1215

Variable Documentation

◆ LatchWaitSet

WaitEventSet* LatchWaitSet
static

Definition at line 134 of file latch.c.

◆ selfpipe_owner_pid

int selfpipe_owner_pid = 0
static

Definition at line 148 of file latch.c.

Referenced by InitializeLatchSupport(), InitLatch(), and OwnLatch().

◆ selfpipe_readfd

int selfpipe_readfd = -1
static

◆ selfpipe_writefd

int selfpipe_writefd = -1
static

Definition at line 145 of file latch.c.

Referenced by InitializeLatchSupport(), and sendSelfPipeByte().

◆ waiting

volatile sig_atomic_t waiting = false
static