From 6cdba2a3e68b23e4bec06e9db3feffdf64cd80cb Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 6 Dec 2022 16:24:05 +1300
Subject: [PATCH v5 3/4] 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, but we should adjust our counter.
For poll and Windows systems, nothing special is required.  On all
systems we free the memory.

Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKG%2BZ-HpOj1JsO9eWUP%2Bar7npSVinsC_npxSy%2BjdOMsx%3DGg%40mail.gmail.com
---
 src/backend/storage/ipc/latch.c | 17 +++++++++++++++++
 src/include/storage/latch.h     |  1 +
 2 files changed, 18 insertions(+)

diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index b32c96b63d..de4fbcdfb9 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 c55838db60..63a1fc440c 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);
-- 
2.35.1

