* Launch parallel workers. */
| 585 | * Launch parallel workers. |
| 586 | */ |
| 587 | void |
| 588 | LaunchParallelWorkers(ParallelContext *pcxt) |
| 589 | { |
| 590 | MemoryContext oldcontext; |
| 591 | BackgroundWorker worker; |
| 592 | int i; |
| 593 | bool any_registrations_failed = false; |
| 594 | |
| 595 | /* Skip this if we have no workers. */ |
| 596 | if (pcxt->nworkers == 0 || pcxt->nworkers_to_launch == 0) |
| 597 | return; |
| 598 | |
| 599 | /* We need to be a lock group leader. */ |
| 600 | BecomeLockGroupLeader(); |
| 601 | |
| 602 | /* If we do have workers, we'd better have a DSM segment. */ |
| 603 | Assert(pcxt->seg != NULL); |
| 604 | |
| 605 | /* We might be running in a short-lived memory context. */ |
| 606 | oldcontext = MemoryContextSwitchTo(TopTransactionContext); |
| 607 | |
| 608 | /* Configure a worker. */ |
| 609 | memset(&worker, 0, sizeof(worker)); |
| 610 | snprintf(worker.bgw_name, BGW_MAXLEN, "parallel worker for PID %d", |
| 611 | MyProcPid); |
| 612 | snprintf(worker.bgw_type, BGW_MAXLEN, "parallel worker"); |
| 613 | worker.bgw_flags = |
| 614 | BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION |
| 615 | | BGWORKER_CLASS_PARALLEL; |
| 616 | worker.bgw_start_time = BgWorkerStart_ConsistentState; |
| 617 | worker.bgw_restart_time = BGW_NEVER_RESTART; |
| 618 | sprintf(worker.bgw_library_name, "postgres"); |
| 619 | sprintf(worker.bgw_function_name, "ParallelWorkerMain"); |
| 620 | worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(pcxt->seg)); |
| 621 | worker.bgw_notify_pid = MyProcPid; |
| 622 | |
| 623 | /* |
| 624 | * Start workers. |
| 625 | * |
| 626 | * The caller must be able to tolerate ending up with fewer workers than |
| 627 | * expected, so there is no need to throw an error here if registration |
| 628 | * fails. It wouldn't help much anyway, because registering the worker in |
| 629 | * no way guarantees that it will start up and initialize successfully. |
| 630 | */ |
| 631 | for (i = 0; i < pcxt->nworkers_to_launch; ++i) |
| 632 | { |
| 633 | memcpy(worker.bgw_extra, &i, sizeof(int)); |
| 634 | if (!any_registrations_failed && |
| 635 | RegisterDynamicBackgroundWorker(&worker, |
| 636 | &pcxt->worker[i].bgwhandle)) |
| 637 | { |
| 638 | shm_mq_set_handle(pcxt->worker[i].error_mqh, |
| 639 | pcxt->worker[i].bgwhandle); |
| 640 | pcxt->nworkers_launched++; |
| 641 | } |
| 642 | else |
| 643 | { |
| 644 | /* |
no test coverage detected