Hi,

I tried to implement a static background(bg) worker without shared
memory access (BGWORKER_SHMEM_ACCESS), it worked fine on Linux machine
where EXEC_BACKEND is not defined(thanks to the fork() implementation
which does great job to get the global state from the
postmaster(parent) to bg worker(child)).

However, the problem arised, when I switched to EXEC_BACKEND mode, it
seems it doesn't. I digged a bit and the following is my analysis: for
EXEC_BACKEND cases, (say on Windows platforms where fork() doesn't
exist) the way postmaster creates a background worker is entirely
different. It is done through SubPostmasterMain and the global state
from the postmaster is shared with the background worker via shared
memory. MyLatch variable also gets created in shared mode. And having
no shared memory access for the worker for EXEC_BACKEND cases(in
StartBackgroundWorker, the shared memory segments get detached), the
worker fails to receive all the global state from the postmaster.
Looks like the background worker needs to have the
BGWORKER_SHMEM_ACCESS flag while registering for EXEC_BACKEND cases.

Please feel free to correct me if I miss anything here.

If the above analysis looks fine, then please find a patch that adds
some info in bgworker.sgml and bgworker.h.

Thoughts?

With Regards,
Bharath Rupireddy.
EnterpriseDB: http://www.enterprisedb.com
From 6117cf28a14ed1861f9cae2f83fccadf75504c43 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddy@enterprisedb.com>
Date: Fri, 31 Jul 2020 16:42:05 +0530
Subject: [PATCH v1] Background worker shared memory access for EXEC_BACKEND
 cases

For EXEC_BACKEND cases, (say on Windows platforms where fork()
doesn't exist) the way postmaster creates a background worker is
different. It is done through SubPostmasterMain and the global
state from the postmaster is shared with the background worker
via shared memory. And having no shared memory access for the
worker for EXEC_BACKEND cases, (in StartBackgroundWorker, the
shared memory segments get detached) the worker fails to receive
all the global state from the postmaster. Looks like the background
worker needs to have the BGWORKER_SHMEM_ACCESS flag while
registering for EXEC_BACKEND cases.
---
 doc/src/sgml/bgworker.sgml        | 13 ++++++++++++-
 src/include/postmaster/bgworker.h | 14 ++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml
index 6e1cf121de..7e2b22eedc 100644
--- a/doc/src/sgml/bgworker.sgml
+++ b/doc/src/sgml/bgworker.sgml
@@ -89,7 +89,18 @@ typedef struct BackgroundWorker
        cannot access any of <productname>PostgreSQL's</productname> shared
        data structures, such as heavyweight or lightweight locks, shared
        buffers, or any custom data structures which the worker itself may
-       wish to create and use.
+       wish to create and use. If the background worker doesn't need shared
+       memory access, on non-EXEC_BACKEND cases (such as Unix/Linux platforms)
+       it is fine, since the worker gets all the global state required from the
+       postmaster by the way the fork() is implemented. However, for EXEC_BACKEND
+       cases, (say on Windows platforms where fork() doesn't exist) the way
+       postmaster creates a background worker is different. It is done through
+       SubPostmasterMain and the global state from the postmaster is shared
+       with the background worker via shared memory. And having no shared memory
+       access for the worker for EXEC_BACKEND cases, (in StartBackgroundWorker,
+       the shared memory segments get detached) the worker fails to receive all the
+       global state from the postmaster. Hence the background worker needs to have
+       BGWORKER_SHMEM_ACCESS flag while registering for EXEC_BACKEND cases.
       </para>
      </listitem>
     </varlistentry>
diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h
index 4c6ebaa41b..88d1ea74f0 100644
--- a/src/include/postmaster/bgworker.h
+++ b/src/include/postmaster/bgworker.h
@@ -51,6 +51,20 @@
  */
 #define BGWORKER_SHMEM_ACCESS						0x0001
 
+/*
+ * If the background worker doesn't need shared memory access, on non-EXEC_BACKEND
+ * cases (such as Unix/Linux platforms) it is fine, since the worker gets all the
+ * global state required from the postmaster by the way the fork() is implemented.
+ * However, for EXEC_BACKEND cases, (say on Windows platforms where fork() doesn't
+ * exist) the way postmaster creates a background worker is different. It is done
+ * through SubPostmasterMain and the global state from the postmaster is shared
+ * with the background worker via shared memory. And having no shared memory access
+ * for the worker for EXEC_BACKEND cases, (in StartBackgroundWorker, the shared
+ * memory segments get detached) the worker fails to receive all the global state
+ * from the postmaster. Hence the background worker needs to have BGWORKER_SHMEM_ACCESS
+ * flag while registering for EXEC_BACKEND cases.
+ */
+
 /*
  * This flag means the bgworker requires a database connection.  The connection
  * is not established automatically; the worker must establish it later.
-- 
2.25.1

Reply via email to