48{
54 int myworkernumber;
56
57 /*
58 * Establish signal handlers.
59 *
60 * We want CHECK_FOR_INTERRUPTS() to kill off this worker process just as
61 * it would a normal user backend. To make that happen, we use die().
62 */
65
66 /*
67 * Connect to the dynamic shared memory segment.
68 *
69 * The backend that registered this worker passed us the ID of a shared
70 * memory segment to which we must attach for further instructions. Once
71 * we've mapped the segment in our address space, attach to the table of
72 * contents so we can locate the various data structures we'll need to
73 * find within the segment.
74 *
75 * Note: at this point, we have not created any ResourceOwner in this
76 * process. This will result in our DSM mapping surviving until process
77 * exit, which is fine. If there were a ResourceOwner, it would acquire
78 * ownership of the mapping, but we have no need for that.
79 */
81 if (seg == NULL)
83 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
84 errmsg(
"unable to map dynamic shared memory segment")));
86 if (toc == NULL)
88 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
89 errmsg(
"bad magic number in dynamic shared memory segment")));
90
91 /*
92 * Acquire a worker number.
93 *
94 * By convention, the process registering this background worker should
95 * have stored the control structure at key 0. We look up that key to
96 * find it. Our worker number gives our identity: there may be just one
97 * worker involved in this parallel operation, or there may be many.
98 */
105 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
106 errmsg(
"too many message queue testing workers already")));
107
108 /*
109 * Attach to the appropriate message queues.
110 */
112
113 /*
114 * Indicate that we're fully initialized and ready to begin the main part
115 * of the parallel operation.
116 *
117 * Once we signal that we're ready, the user backend is entitled to assume
118 * that our on_dsm_detach callbacks will fire before we disconnect from
119 * the shared memory segment and exit. Generally, that means we must have
120 * attached to all relevant dynamic shared memory data structures by now.
121 */
126 if (registrant == NULL)
127 {
128 elog(
DEBUG1,
"registrant backend has exited prematurely");
130 }
132
133 /* Do the work. */
135
136 /*
137 * We're done. For cleanliness, explicitly detach from the shared memory
138 * segment (that would happen anyway during process exit, though).
139 */
142}
void BackgroundWorkerUnblockSignals(void)
void dsm_detach(dsm_segment *seg)
void * dsm_segment_address(dsm_segment *seg)
dsm_segment * dsm_attach(dsm_handle h)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void SetLatch(Latch *latch)
static uint32 DatumGetUInt32(Datum X)
BackgroundWorker * MyBgworkerEntry
PGPROC * BackendPidGetProc(int pid)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
shm_toc * shm_toc_attach(uint64 magic, void *address)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
static void attach_to_queues(dsm_segment *seg, shm_toc *toc, int myworkernumber, shm_mq_handle **inqhp, shm_mq_handle **outqhp)
static void copy_messages(shm_mq_handle *inqh, shm_mq_handle *outqh)
#define PG_TEST_SHM_MQ_MAGIC