PostgreSQL Source Code  git master
latch.h File Reference
#include <signal.h>
Include dependency graph for latch.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Latch
 
struct  WaitEvent
 

Macros

#define WL_LATCH_SET   (1 << 0)
 
#define WL_SOCKET_READABLE   (1 << 1)
 
#define WL_SOCKET_WRITEABLE   (1 << 2)
 
#define WL_TIMEOUT   (1 << 3) /* not for WaitEventSetWait() */
 
#define WL_POSTMASTER_DEATH   (1 << 4)
 
#define WL_EXIT_ON_PM_DEATH   (1 << 5)
 
#define WL_SOCKET_CONNECTED   WL_SOCKET_WRITEABLE
 
#define WL_SOCKET_MASK
 

Typedefs

typedef struct Latch Latch
 
typedef struct WaitEvent WaitEvent
 
typedef struct WaitEventSet WaitEventSet
 

Functions

void InitializeLatchSupport (void)
 
void InitLatch (Latch *latch)
 
void InitSharedLatch (Latch *latch)
 
void OwnLatch (Latch *latch)
 
void DisownLatch (Latch *latch)
 
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)
 
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 InitializeLatchWaitSet (void)
 
void latch_sigusr1_handler (void)
 

Macro Definition Documentation

◆ WL_EXIT_ON_PM_DEATH

◆ WL_LATCH_SET

◆ WL_POSTMASTER_DEATH

◆ WL_SOCKET_CONNECTED

#define WL_SOCKET_CONNECTED   WL_SOCKET_WRITEABLE

Definition at line 134 of file latch.h.

Referenced by libpqrcv_connect(), ModifyWaitEvent(), and WaitEventSetWait().

◆ WL_SOCKET_MASK

#define WL_SOCKET_MASK
Value:
WL_SOCKET_WRITEABLE | \
WL_SOCKET_CONNECTED)
#define WL_SOCKET_READABLE
Definition: latch.h:125

Definition at line 137 of file latch.h.

Referenced by AddWaitEventToSet(), WaitEventSetWait(), and WaitLatchOrSocket().

◆ WL_SOCKET_READABLE

◆ WL_SOCKET_WRITEABLE

◆ WL_TIMEOUT

Typedef Documentation

◆ Latch

typedef struct Latch Latch

◆ WaitEvent

typedef struct WaitEvent WaitEvent

◆ WaitEventSet

typedef struct WaitEventSet WaitEventSet

Definition at line 153 of file latch.h.

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

◆ 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 1929 of file latch.c.

References sendSelfPipeByte(), and waiting.

Referenced by bgworker_sigusr1_handler(), and procsignal_sigusr1_handler().

1930 {
1931  if (waiting)
1932  sendSelfPipeByte();
1933 }
static void sendSelfPipeByte(void)
Definition: latch.c:1939
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, MyProcPid, WaitEventSet::nevents, Latch::owner_pid, 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  if (latch && latch->owner_pid != MyProcPid)
928  elog(ERROR, "cannot wait on a latch owned by another process");
929  set->latch = latch;
930  /*
931  * On Unix, we don't need to modify the kernel object because the
932  * underlying pipe is the same for all latches so we can return
933  * immediately. On Windows, we need to update our array of handles,
934  * but we leave the old one in place and tolerate spurious wakeups if
935  * the latch is disabled.
936  */
937 #if defined(WAIT_USE_WIN32)
938  if (!latch)
939  return;
940 #else
941  return;
942 #endif
943  }
944 
945 #if defined(WAIT_USE_EPOLL)
946  WaitEventAdjustEpoll(set, event, EPOLL_CTL_MOD);
947 #elif defined(WAIT_USE_KQUEUE)
948  WaitEventAdjustKqueue(set, event, old_events);
949 #elif defined(WAIT_USE_POLL)
950  WaitEventAdjustPoll(set, event);
951 #elif defined(WAIT_USE_WIN32)
952  WaitEventAdjustWin32(set, event);
953 #endif
954 }
int MyProcPid
Definition: globals.c:40
#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
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

◆ 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

◆ 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:1939
#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 1230 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().

1233 {
1234  int returned_events = 0;
1236  instr_time cur_time;
1237  long cur_timeout = -1;
1238 
1239  Assert(nevents > 0);
1240 
1241  /*
1242  * Initialize timeout if requested. We must record the current time so
1243  * that we can determine the remaining timeout if interrupted.
1244  */
1245  if (timeout >= 0)
1246  {
1247  INSTR_TIME_SET_CURRENT(start_time);
1248  Assert(timeout >= 0 && timeout <= INT_MAX);
1249  cur_timeout = timeout;
1250  }
1251 
1252  pgstat_report_wait_start(wait_event_info);
1253 
1254 #ifndef WIN32
1255  waiting = true;
1256 #else
1257  /* Ensure that signals are serviced even if latch is already set */
1259 #endif
1260  while (returned_events == 0)
1261  {
1262  int rc;
1263 
1264  /*
1265  * Check if the latch is set already. If so, leave the loop
1266  * immediately, avoid blocking again. We don't attempt to report any
1267  * other events that might also be satisfied.
1268  *
1269  * If someone sets the latch between this and the
1270  * WaitEventSetWaitBlock() below, the setter will write a byte to the
1271  * pipe (or signal us and the signal handler will do that), and the
1272  * readiness routine will return immediately.
1273  *
1274  * On unix, If there's a pending byte in the self pipe, we'll notice
1275  * whenever blocking. Only clearing the pipe in that case avoids
1276  * having to drain it every time WaitLatchOrSocket() is used. Should
1277  * the pipe-buffer fill up we're still ok, because the pipe is in
1278  * nonblocking mode. It's unlikely for that to happen, because the
1279  * self pipe isn't filled unless we're blocking (waiting = true), or
1280  * from inside a signal handler in latch_sigusr1_handler().
1281  *
1282  * On windows, we'll also notice if there's a pending event for the
1283  * latch when blocking, but there's no danger of anything filling up,
1284  * as "Setting an event that is already set has no effect.".
1285  *
1286  * Note: we assume that the kernel calls involved in latch management
1287  * will provide adequate synchronization on machines with weak memory
1288  * ordering, so that we cannot miss seeing is_set if a notification
1289  * has already been queued.
1290  */
1291  if (set->latch && set->latch->is_set)
1292  {
1293  occurred_events->fd = PGINVALID_SOCKET;
1294  occurred_events->pos = set->latch_pos;
1295  occurred_events->user_data =
1296  set->events[set->latch_pos].user_data;
1297  occurred_events->events = WL_LATCH_SET;
1298  occurred_events++;
1299  returned_events++;
1300 
1301  break;
1302  }
1303 
1304  /*
1305  * Wait for events using the readiness primitive chosen at the top of
1306  * this file. If -1 is returned, a timeout has occurred, if 0 we have
1307  * to retry, everything >= 1 is the number of returned events.
1308  */
1309  rc = WaitEventSetWaitBlock(set, cur_timeout,
1310  occurred_events, nevents);
1311 
1312  if (rc == -1)
1313  break; /* timeout occurred */
1314  else
1315  returned_events = rc;
1316 
1317  /* If we're not done, update cur_timeout for next iteration */
1318  if (returned_events == 0 && timeout >= 0)
1319  {
1320  INSTR_TIME_SET_CURRENT(cur_time);
1321  INSTR_TIME_SUBTRACT(cur_time, start_time);
1322  cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time);
1323  if (cur_timeout <= 0)
1324  break;
1325  }
1326  }
1327 #ifndef WIN32
1328  waiting = false;
1329 #endif
1330 
1332 
1333  return returned_events;
1334 }
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

◆ 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:1230

◆ 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:1230