summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2022-12-23 07:26:52 +0000
committerThomas Munro2022-12-23 07:34:03 +0000
commitb5d0f8ec01c021452203b2fd3921c9b55f6c3cd3 (patch)
tree6c7fb1df6165685e4c0e164ec62d3db36f5b4a6e
parent1f0019de2fe374fa54fca277f36c2e754894db30 (diff)
Allow parent's WaitEventSets to be freed after fork().
An epoll fd belonging to the parent should be closed in the child. A kqueue fd is automatically closed by fork(), but we should still adjust our counter. For poll and Windows systems, nothing special is required. On all systems we free the memory. No caller yet, but we'll need this if we start using WaitEventSet in the postmaster as planned. Reviewed-by: Andres Freund <[email protected]> Discussion: https://postgr.es/m/CA%2BhUKG%2BZ-HpOj1JsO9eWUP%2Bar7npSVinsC_npxSy%2BjdOMsx%3DGg%40mail.gmail.com
-rw-r--r--src/backend/storage/ipc/latch.c17
-rw-r--r--src/include/storage/latch.h1
2 files changed, 18 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index b32c96b63d3..de4fbcdfb94 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -869,6 +869,23 @@ FreeWaitEventSet(WaitEventSet *set)
pfree(set);
}
+/*
+ * Free a previously created WaitEventSet in a child process after a fork().
+ */
+void
+FreeWaitEventSetAfterFork(WaitEventSet *set)
+{
+#if defined(WAIT_USE_EPOLL)
+ close(set->epoll_fd);
+ ReleaseExternalFD();
+#elif defined(WAIT_USE_KQUEUE)
+ /* kqueues are not normally inherited by child processes */
+ ReleaseExternalFD();
+#endif
+
+ pfree(set);
+}
+
/* ---
* Add an event to the set. Possible events are:
* - WL_LATCH_SET: Wait for the latch to be set
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index c55838db607..63a1fc440c4 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -175,6 +175,7 @@ extern void ShutdownLatchSupport(void);
extern WaitEventSet *CreateWaitEventSet(MemoryContext context, int nevents);
extern void FreeWaitEventSet(WaitEventSet *set);
+extern void FreeWaitEventSetAfterFork(WaitEventSet *set);
extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd,
Latch *latch, void *user_data);
extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch);