1 /*--------------------------------------------------------------------
3 * POSTGRES pluggable background workers implementation
5 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
8 * src/backend/postmaster/bgworker.c
10 *-------------------------------------------------------------------------
17 #include "miscadmin.h"
18 #include "libpq/pqsignal.h"
19 #include "postmaster/bgworker_internals.h"
20 #include "postmaster/postmaster.h"
21 #include "storage/barrier.h"
22 #include "storage/dsm.h"
23 #include "storage/ipc.h"
24 #include "storage/latch.h"
25 #include "storage/lwlock.h"
26 #include "storage/pg_shmem.h"
27 #include "storage/pmsignal.h"
28 #include "storage/proc.h"
29 #include "storage/procsignal.h"
30 #include "storage/shmem.h"
31 #include "tcop/tcopprot.h"
32 #include "utils/ascii.h"
33 #include "utils/ps_status.h"
34 #include "utils/timeout.h"
37 * The postmaster's list of registered background workers, in private memory.
39 slist_head BackgroundWorkerList = SLIST_STATIC_INIT(BackgroundWorkerList);
42 * BackgroundWorkerSlots exist in shared memory and can be accessed (via
43 * the BackgroundWorkerArray) by both the postmaster and by regular backends.
44 * However, the postmaster cannot take locks, even spinlocks, because this
45 * might allow it to crash or become wedged if shared memory gets corrupted.
46 * Such an outcome is intolerable. Therefore, we need a lockless protocol
47 * for coordinating access to this data.
49 * The 'in_use' flag is used to hand off responsibility for the slot between
50 * the postmaster and the rest of the system. When 'in_use' is false,
51 * the postmaster will ignore the slot entirely, except for the 'in_use' flag
52 * itself, which it may read. In this state, regular backends may modify the
53 * slot. Once a backend sets 'in_use' to true, the slot becomes the
54 * responsibility of the postmaster. Regular backends may no longer modify it,
55 * but the postmaster may examine it. Thus, a backend initializing a slot
56 * must fully initialize the slot - and insert a write memory barrier - before
57 * marking it as in use.
59 * As an exception, however, even when the slot is in use, regular backends
60 * may set the 'terminate' flag for a slot, telling the postmaster not
61 * to restart it. Once the background worker is no longer running, the slot
62 * will be released for reuse.
64 * In addition to coordinating with the postmaster, backends modifying this
65 * data structure must coordinate with each other. Since they can take locks,
66 * this is straightforward: any backend wishing to manipulate a slot must
67 * take BackgroundWorkerLock in exclusive mode. Backends wishing to read
68 * data that might get concurrently modified by other backends should take
69 * this lock in shared mode. No matter what, backends reading this data
70 * structure must be able to tolerate concurrent modifications by the
73 typedef struct BackgroundWorkerSlot
77 pid_t pid; /* InvalidPid = not started yet; 0 = dead */
78 uint64 generation; /* incremented when slot is recycled */
79 BackgroundWorker worker;
80 } BackgroundWorkerSlot;
82 typedef struct BackgroundWorkerArray
85 BackgroundWorkerSlot slot[FLEXIBLE_ARRAY_MEMBER];
86 } BackgroundWorkerArray;
88 struct BackgroundWorkerHandle
94 static BackgroundWorkerArray *BackgroundWorkerData;
97 * Calculate shared memory needed.
100 BackgroundWorkerShmemSize(void)
104 /* Array of workers is variably sized. */
105 size = offsetof(BackgroundWorkerArray, slot);
106 size = add_size(size, mul_size(max_worker_processes,
107 sizeof(BackgroundWorkerSlot)));
113 * Initialize shared memory.
116 BackgroundWorkerShmemInit(void)
120 BackgroundWorkerData = ShmemInitStruct("Background Worker Data",
121 BackgroundWorkerShmemSize(),
123 if (!IsUnderPostmaster)
128 BackgroundWorkerData->total_slots = max_worker_processes;
131 * Copy contents of worker list into shared memory. Record the shared
132 * memory slot assigned to each worker. This ensures a 1-to-1
133 * correspondence between the postmaster's private list and the array
136 slist_foreach(siter, &BackgroundWorkerList)
138 BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
139 RegisteredBgWorker *rw;
141 rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
142 Assert(slotno < max_worker_processes);
144 slot->terminate = false;
145 slot->pid = InvalidPid;
146 slot->generation = 0;
147 rw->rw_shmem_slot = slotno;
148 rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */
149 memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
154 * Mark any remaining slots as not in use.
156 while (slotno < max_worker_processes)
158 BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
160 slot->in_use = false;
169 * Search the postmaster's backend-private list of RegisteredBgWorker objects
170 * for the one that maps to the given slot number.
172 static RegisteredBgWorker *
173 FindRegisteredWorkerBySlotNumber(int slotno)
177 slist_foreach(siter, &BackgroundWorkerList)
179 RegisteredBgWorker *rw;
181 rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
182 if (rw->rw_shmem_slot == slotno)
190 * Notice changes to shared memory made by other backends. This code
191 * runs in the postmaster, so we must be very careful not to assume that
192 * shared memory contents are sane. Otherwise, a rogue backend could take
193 * out the postmaster.
196 BackgroundWorkerStateChange(void)
201 * The total number of slots stored in shared memory should match our
202 * notion of max_worker_processes. If it does not, something is very
203 * wrong. Further down, we always refer to this value as
204 * max_worker_processes, in case shared memory gets corrupted while we're
207 if (max_worker_processes != BackgroundWorkerData->total_slots)
210 "inconsistent background worker state (max_worker_processes=%d, total_slots=%d",
211 max_worker_processes,
212 BackgroundWorkerData->total_slots);
217 * Iterate through slots, looking for newly-registered workers or workers
220 for (slotno = 0; slotno < max_worker_processes; ++slotno)
222 BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
223 RegisteredBgWorker *rw;
229 * Make sure we don't see the in_use flag before the updated slot
234 /* See whether we already know about this worker. */
235 rw = FindRegisteredWorkerBySlotNumber(slotno);
239 * In general, the worker data can't change after it's initially
240 * registered. However, someone can set the terminate flag.
242 if (slot->terminate && !rw->rw_terminate)
244 rw->rw_terminate = true;
246 kill(rw->rw_pid, SIGTERM);
249 /* Report never-started, now-terminated worker as dead. */
250 ReportBackgroundWorkerPID(rw);
257 * If the worker is marked for termination, we don't need to add it to
258 * the registered workers list; we can just free the slot. However, if
259 * bgw_notify_pid is set, the process that registered the worker may
260 * need to know that we've processed the terminate request, so be sure
268 * We need a memory barrier here to make sure that the load of
269 * bgw_notify_pid completes before the store to in_use.
271 notify_pid = slot->worker.bgw_notify_pid;
274 slot->in_use = false;
276 kill(notify_pid, SIGUSR1);
282 * Copy the registration data into the registered workers list.
284 rw = malloc(sizeof(RegisteredBgWorker));
288 (errcode(ERRCODE_OUT_OF_MEMORY),
289 errmsg("out of memory")));
294 * Copy strings in a paranoid way. If shared memory is corrupted, the
295 * source data might not even be NUL-terminated.
297 ascii_safe_strlcpy(rw->rw_worker.bgw_name,
298 slot->worker.bgw_name, BGW_MAXLEN);
299 ascii_safe_strlcpy(rw->rw_worker.bgw_library_name,
300 slot->worker.bgw_library_name, BGW_MAXLEN);
301 ascii_safe_strlcpy(rw->rw_worker.bgw_function_name,
302 slot->worker.bgw_function_name, BGW_MAXLEN);
305 * Copy various fixed-size fields.
307 * flags, start_time, and restart_time are examined by the postmaster,
308 * but nothing too bad will happen if they are corrupted. The
309 * remaining fields will only be examined by the child process. It
310 * might crash, but we won't.
312 rw->rw_worker.bgw_flags = slot->worker.bgw_flags;
313 rw->rw_worker.bgw_start_time = slot->worker.bgw_start_time;
314 rw->rw_worker.bgw_restart_time = slot->worker.bgw_restart_time;
315 rw->rw_worker.bgw_main = slot->worker.bgw_main;
316 rw->rw_worker.bgw_main_arg = slot->worker.bgw_main_arg;
319 * Copy the PID to be notified about state changes, but only if the
320 * postmaster knows about a backend with that PID. It isn't an error
321 * if the postmaster doesn't know about the PID, because the backend
322 * that requested the worker could have died (or been killed) just
323 * after doing so. Nonetheless, at least until we get some experience
324 * with how this plays out in the wild, log a message at a relative
327 rw->rw_worker.bgw_notify_pid = slot->worker.bgw_notify_pid;
328 if (!PostmasterMarkPIDForWorkerNotify(rw->rw_worker.bgw_notify_pid))
330 elog(DEBUG1, "worker notification PID %lu is not valid",
331 (long) rw->rw_worker.bgw_notify_pid);
332 rw->rw_worker.bgw_notify_pid = 0;
335 /* Initialize postmaster bookkeeping. */
336 rw->rw_backend = NULL;
338 rw->rw_child_slot = 0;
339 rw->rw_crashed_at = 0;
340 rw->rw_shmem_slot = slotno;
341 rw->rw_terminate = false;
345 (errmsg("registering background worker \"%s\"",
346 rw->rw_worker.bgw_name)));
348 slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
353 * Forget about a background worker that's no longer needed.
355 * The worker must be identified by passing an slist_mutable_iter that
356 * points to it. This convention allows deletion of workers during
357 * searches of the worker list, and saves having to search the list again.
359 * This function must be invoked only in the postmaster.
362 ForgetBackgroundWorker(slist_mutable_iter *cur)
364 RegisteredBgWorker *rw;
365 BackgroundWorkerSlot *slot;
367 rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
369 Assert(rw->rw_shmem_slot < max_worker_processes);
370 slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
371 slot->in_use = false;
374 (errmsg("unregistering background worker \"%s\"",
375 rw->rw_worker.bgw_name)));
377 slist_delete_current(cur);
382 * Report the PID of a newly-launched background worker in shared memory.
384 * This function should only be called from the postmaster.
387 ReportBackgroundWorkerPID(RegisteredBgWorker *rw)
389 BackgroundWorkerSlot *slot;
391 Assert(rw->rw_shmem_slot < max_worker_processes);
392 slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
393 slot->pid = rw->rw_pid;
395 if (rw->rw_worker.bgw_notify_pid != 0)
396 kill(rw->rw_worker.bgw_notify_pid, SIGUSR1);
400 * Cancel SIGUSR1 notifications for a PID belonging to an exiting backend.
402 * This function should only be called from the postmaster.
405 BackgroundWorkerStopNotifications(pid_t pid)
409 slist_foreach(siter, &BackgroundWorkerList)
411 RegisteredBgWorker *rw;
413 rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
414 if (rw->rw_worker.bgw_notify_pid == pid)
415 rw->rw_worker.bgw_notify_pid = 0;
420 * Reset background worker crash state.
422 * We assume that, after a crash-and-restart cycle, background workers without
423 * the never-restart flag should be restarted immediately, instead of waiting
424 * for bgw_restart_time to elapse.
427 ResetBackgroundWorkerCrashTimes(void)
429 slist_mutable_iter iter;
431 slist_foreach_modify(iter, &BackgroundWorkerList)
433 RegisteredBgWorker *rw;
435 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
438 * For workers that should not be restarted, we don't want to lose the
439 * information that they have crashed; otherwise, they would be
440 * restarted, which is wrong.
442 if (rw->rw_worker.bgw_restart_time != BGW_NEVER_RESTART)
443 rw->rw_crashed_at = 0;
449 * In EXEC_BACKEND mode, workers use this to retrieve their details from
453 BackgroundWorkerEntry(int slotno)
455 static BackgroundWorker myEntry;
456 BackgroundWorkerSlot *slot;
458 Assert(slotno < BackgroundWorkerData->total_slots);
459 slot = &BackgroundWorkerData->slot[slotno];
460 Assert(slot->in_use);
462 /* must copy this in case we don't intend to retain shmem access */
463 memcpy(&myEntry, &slot->worker, sizeof myEntry);
469 * Complain about the BackgroundWorker definition using error level elevel.
470 * Return true if it looks ok, false if not (unless elevel >= ERROR, in
471 * which case we won't return at all in the not-OK case).
474 SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
476 /* sanity check for flags */
477 if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
479 if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
482 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
483 errmsg("background worker \"%s\": must attach to shared memory in order to request a database connection",
488 if (worker->bgw_start_time == BgWorkerStart_PostmasterStart)
491 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
492 errmsg("background worker \"%s\": cannot request database access if starting at postmaster start",
497 /* XXX other checks? */
500 if ((worker->bgw_restart_time < 0 &&
501 worker->bgw_restart_time != BGW_NEVER_RESTART) ||
502 (worker->bgw_restart_time > USECS_PER_DAY / 1000))
505 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
506 errmsg("background worker \"%s\": invalid restart interval",
515 bgworker_quickdie(SIGNAL_ARGS)
517 sigaddset(&BlockSig, SIGQUIT); /* prevent nested calls */
518 PG_SETMASK(&BlockSig);
521 * We DO NOT want to run proc_exit() callbacks -- we're here because
522 * shared memory may be corrupted, so we don't want to try to clean up our
523 * transaction. Just nail the windows shut and get out of town. Now that
524 * there's an atexit callback to prevent third-party code from breaking
525 * things by calling exit() directly, we have to reset the callbacks
526 * explicitly to make this work as intended.
531 * Note we do exit(2) not exit(0). This is to force the postmaster into a
532 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
533 * backend. This is necessary precisely because we don't clean up our
534 * shared memory state. (The "dead man switch" mechanism in pmsignal.c
535 * should ensure the postmaster sees this as a crash, too, but no harm in
536 * being doubly sure.)
542 * Standard SIGTERM handler for background workers
545 bgworker_die(SIGNAL_ARGS)
547 PG_SETMASK(&BlockSig);
550 (errcode(ERRCODE_ADMIN_SHUTDOWN),
551 errmsg("terminating background worker \"%s\" due to administrator command",
552 MyBgworkerEntry->bgw_name)));
556 * Standard SIGUSR1 handler for unconnected workers
558 * Here, we want to make sure an unconnected worker will at least heed
562 bgworker_sigusr1_handler(SIGNAL_ARGS)
564 int save_errno = errno;
566 latch_sigusr1_handler();
572 * Start a new background worker
574 * This is the main entry point for background worker, to be called from
578 StartBackgroundWorker(void)
580 sigjmp_buf local_sigjmp_buf;
582 BackgroundWorker *worker = MyBgworkerEntry;
583 bgworker_main_type entrypt;
586 elog(FATAL, "unable to find bgworker entry");
588 IsBackgroundWorker = true;
590 /* Identify myself via ps */
591 snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name);
592 init_ps_display(buf, "", "", "");
595 * If we're not supposed to have shared memory access, then detach from
596 * shared memory. If we didn't request shared memory access, the
597 * postmaster won't force a cluster-wide restart if we exit unexpectedly,
598 * so we'd better make sure that we don't mess anything up that would
599 * require that sort of cleanup.
601 if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0)
605 PGSharedMemoryDetach();
608 SetProcessingMode(InitProcessing);
610 /* Apply PostAuthDelay */
611 if (PostAuthDelay > 0)
612 pg_usleep(PostAuthDelay * 1000000L);
615 * Set up signal handlers.
617 if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
620 * SIGINT is used to signal canceling the current action
622 pqsignal(SIGINT, StatementCancelHandler);
623 pqsignal(SIGUSR1, procsignal_sigusr1_handler);
624 pqsignal(SIGFPE, FloatExceptionHandler);
626 /* XXX Any other handlers needed here? */
630 pqsignal(SIGINT, SIG_IGN);
631 pqsignal(SIGUSR1, bgworker_sigusr1_handler);
632 pqsignal(SIGFPE, SIG_IGN);
634 pqsignal(SIGTERM, bgworker_die);
635 pqsignal(SIGHUP, SIG_IGN);
637 pqsignal(SIGQUIT, bgworker_quickdie);
638 InitializeTimeouts(); /* establishes SIGALRM handler */
640 pqsignal(SIGPIPE, SIG_IGN);
641 pqsignal(SIGUSR2, SIG_IGN);
642 pqsignal(SIGCHLD, SIG_DFL);
645 * If an exception is encountered, processing resumes here.
647 * See notes in postgres.c about the design of this coding.
649 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
651 /* Since not using PG_TRY, must reset error stack by hand */
652 error_context_stack = NULL;
654 /* Prevent interrupts while cleaning up */
657 /* Report the error to the server log */
661 * Do we need more cleanup here? For shmem-connected bgworkers, we
662 * will call InitProcess below, which will install ProcKill as exit
663 * callback. That will take care of releasing locks, etc.
670 /* We can now handle ereport(ERROR) */
671 PG_exception_stack = &local_sigjmp_buf;
674 * If the background worker request shared memory access, set that up now;
675 * else, detach all shared memory segments.
677 if (worker->bgw_flags & BGWORKER_SHMEM_ACCESS)
680 * Early initialization. Some of this could be useful even for
681 * background workers that aren't using shared memory, but they can
682 * call the individual startup routines for those subsystems if
688 * Create a per-backend PGPROC struct in shared memory, except in the
689 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must
690 * do this before we can use LWLocks (and in the EXEC_BACKEND case we
691 * already had to do some stuff with LWLocks).
699 * If bgw_main is set, we use that value as the initial entrypoint.
700 * However, if the library containing the entrypoint wasn't loaded at
701 * postmaster startup time, passing it as a direct function pointer is not
702 * possible. To work around that, we allow callers for whom a function
703 * pointer is not available to pass a library name (which will be loaded,
704 * if necessary) and a function name (which will be looked up in the named
707 if (worker->bgw_main != NULL)
708 entrypt = worker->bgw_main;
710 entrypt = (bgworker_main_type)
711 load_external_function(worker->bgw_library_name,
712 worker->bgw_function_name,
716 * Note that in normal processes, we would call InitPostgres here. For a
717 * worker, however, we don't know what database to connect to, yet; so we
718 * need to wait until the user code does it via
719 * BackgroundWorkerInitializeConnection().
723 * Now invoke the user-defined worker code
725 entrypt(worker->bgw_main_arg);
727 /* ... and if it returns, we're done */
732 * Register a new background worker while processing shared_preload_libraries.
734 * This can only be called in the _PG_init function of a module library
735 * that's loaded by shared_preload_libraries; otherwise it has no effect.
738 RegisterBackgroundWorker(BackgroundWorker *worker)
740 RegisteredBgWorker *rw;
741 static int numworkers = 0;
743 if (!IsUnderPostmaster)
745 (errmsg("registering background worker \"%s\"", worker->bgw_name)));
747 if (!process_shared_preload_libraries_in_progress)
749 if (!IsUnderPostmaster)
751 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
752 errmsg("background worker \"%s\": must be registered in shared_preload_libraries",
757 if (!SanityCheckBackgroundWorker(worker, LOG))
760 if (worker->bgw_notify_pid != 0)
763 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
764 errmsg("background worker \"%s\": only dynamic background workers can request notification",
770 * Enforce maximum number of workers. Note this is overly restrictive: we
771 * could allow more non-shmem-connected workers, because these don't count
772 * towards the MAX_BACKENDS limit elsewhere. For now, it doesn't seem
773 * important to relax this restriction.
775 if (++numworkers > max_worker_processes)
778 (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
779 errmsg("too many background workers"),
780 errdetail_plural("Up to %d background worker can be registered with the current settings.",
781 "Up to %d background workers can be registered with the current settings.",
782 max_worker_processes,
783 max_worker_processes),
784 errhint("Consider increasing the configuration parameter \"max_worker_processes\".")));
789 * Copy the registration data into the registered workers list.
791 rw = malloc(sizeof(RegisteredBgWorker));
795 (errcode(ERRCODE_OUT_OF_MEMORY),
796 errmsg("out of memory")));
800 rw->rw_worker = *worker;
801 rw->rw_backend = NULL;
803 rw->rw_child_slot = 0;
804 rw->rw_crashed_at = 0;
805 rw->rw_terminate = false;
807 slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
811 * Register a new background worker from a regular backend.
813 * Returns true on success and false on failure. Failure typically indicates
814 * that no background worker slots are currently available.
816 * If handle != NULL, we'll set *handle to a pointer that can subsequently
817 * be used as an argument to GetBackgroundWorkerPid(). The caller can
818 * free this pointer using pfree(), if desired.
821 RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
822 BackgroundWorkerHandle **handle)
825 bool success = false;
826 uint64 generation = 0;
829 * We can't register dynamic background workers from the postmaster. If
830 * this is a standalone backend, we're the only process and can't start
831 * any more. In a multi-process environement, it might be theoretically
832 * possible, but we don't currently support it due to locking
833 * considerations; see comments on the BackgroundWorkerSlot data
836 if (!IsUnderPostmaster)
839 if (!SanityCheckBackgroundWorker(worker, ERROR))
842 LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
845 * Look for an unused slot. If we find one, grab it.
847 for (slotno = 0; slotno < BackgroundWorkerData->total_slots; ++slotno)
849 BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
853 memcpy(&slot->worker, worker, sizeof(BackgroundWorker));
854 slot->pid = InvalidPid; /* indicates not started yet */
856 slot->terminate = false;
857 generation = slot->generation;
860 * Make sure postmaster doesn't see the slot as in use before it
861 * sees the new contents.
871 LWLockRelease(BackgroundWorkerLock);
873 /* If we found a slot, tell the postmaster to notice the change. */
875 SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);
878 * If we found a slot and the user has provided a handle, initialize it.
880 if (success && handle)
882 *handle = palloc(sizeof(BackgroundWorkerHandle));
883 (*handle)->slot = slotno;
884 (*handle)->generation = generation;
891 * Get the PID of a dynamically-registered background worker.
893 * If the worker is determined to be running, the return value will be
894 * BGWH_STARTED and *pidp will get the PID of the worker process.
895 * Otherwise, the return value will be BGWH_NOT_YET_STARTED if the worker
896 * hasn't been started yet, and BGWH_STOPPED if the worker was previously
897 * running but is no longer.
899 * In the latter case, the worker may be stopped temporarily (if it is
900 * configured for automatic restart and exited non-zero) or gone for
901 * good (if it exited with code 0 or if it is configured not to restart).
904 GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp)
906 BackgroundWorkerSlot *slot;
909 Assert(handle->slot < max_worker_processes);
910 slot = &BackgroundWorkerData->slot[handle->slot];
913 * We could probably arrange to synchronize access to data using memory
914 * barriers only, but for now, let's just keep it simple and grab the
915 * lock. It seems unlikely that there will be enough traffic here to
916 * result in meaningful contention.
918 LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
921 * The generation number can't be concurrently changed while we hold the
922 * lock. The pid, which is updated by the postmaster, can change at any
923 * time, but we assume such changes are atomic. So the value we read
924 * won't be garbage, but it might be out of date by the time the caller
925 * examines it (but that's unavoidable anyway).
927 if (handle->generation != slot->generation)
933 LWLockRelease(BackgroundWorkerLock);
937 else if (pid == InvalidPid)
938 return BGWH_NOT_YET_STARTED;
944 * Wait for a background worker to start up.
946 * This is like GetBackgroundWorkerPid(), except that if the worker has not
947 * yet started, we wait for it to do so; thus, BGWH_NOT_YET_STARTED is never
948 * returned. However, if the postmaster has died, we give up and return
949 * BGWH_POSTMASTER_DIED, since it that case we know that startup will not
953 WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp)
955 BgwHandleStatus status;
957 bool save_set_latch_on_sigusr1;
959 save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
960 set_latch_on_sigusr1 = true;
968 CHECK_FOR_INTERRUPTS();
970 status = GetBackgroundWorkerPid(handle, &pid);
971 if (status == BGWH_STARTED)
973 if (status != BGWH_NOT_YET_STARTED)
976 rc = WaitLatch(MyLatch,
977 WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
979 if (rc & WL_POSTMASTER_DEATH)
981 status = BGWH_POSTMASTER_DIED;
990 set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
995 set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
1000 * Wait for a background worker to stop.
1002 * If the worker hasn't yet started, or is running, we wait for it to stop
1003 * and then return BGWH_STOPPED. However, if the postmaster has died, we give
1004 * up and return BGWH_POSTMASTER_DIED, because it's the postmaster that
1005 * notifies us when a worker's state changes.
1008 WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
1010 BgwHandleStatus status;
1012 bool save_set_latch_on_sigusr1;
1014 save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
1015 set_latch_on_sigusr1 = true;
1023 CHECK_FOR_INTERRUPTS();
1025 status = GetBackgroundWorkerPid(handle, &pid);
1026 if (status == BGWH_STOPPED)
1029 rc = WaitLatch(&MyProc->procLatch,
1030 WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
1032 if (rc & WL_POSTMASTER_DEATH)
1033 return BGWH_POSTMASTER_DIED;
1035 ResetLatch(&MyProc->procLatch);
1040 set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
1045 set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
1050 * Instruct the postmaster to terminate a background worker.
1052 * Note that it's safe to do this without regard to whether the worker is
1053 * still running, or even if the worker may already have existed and been
1057 TerminateBackgroundWorker(BackgroundWorkerHandle *handle)
1059 BackgroundWorkerSlot *slot;
1060 bool signal_postmaster = false;
1062 Assert(handle->slot < max_worker_processes);
1063 slot = &BackgroundWorkerData->slot[handle->slot];
1065 /* Set terminate flag in shared memory, unless slot has been reused. */
1066 LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1067 if (handle->generation == slot->generation)
1069 slot->terminate = true;
1070 signal_postmaster = true;
1072 LWLockRelease(BackgroundWorkerLock);
1074 /* Make sure the postmaster notices the change to shared memory. */
1075 if (signal_postmaster)
1076 SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);