|
16 | 16 |
|
17 | 17 | #include "miscadmin.h"
|
18 | 18 | #include "libpq/pqsignal.h"
|
| 19 | +#include "access/parallel.h" |
19 | 20 | #include "postmaster/bgworker_internals.h"
|
20 | 21 | #include "postmaster/postmaster.h"
|
21 | 22 | #include "storage/barrier.h"
|
@@ -93,6 +94,25 @@ struct BackgroundWorkerHandle
|
93 | 94 |
|
94 | 95 | static BackgroundWorkerArray *BackgroundWorkerData;
|
95 | 96 |
|
| 97 | +/* |
| 98 | + * List of internal background workers. These are used for mapping the |
| 99 | + * function name to actual function when building with EXEC_BACKEND and also |
| 100 | + * to allow these to be loaded outside of shared_preload_libraries. |
| 101 | + */ |
| 102 | +typedef struct InternalBGWorkerMain |
| 103 | +{ |
| 104 | + char *bgw_function_name; |
| 105 | + bgworker_main_type bgw_main; |
| 106 | +} InternalBGWorkerMain; |
| 107 | + |
| 108 | +static const InternalBGWorkerMain InternalBGWorkers[] = { |
| 109 | + {"ParallelWorkerMain", ParallelWorkerMain}, |
| 110 | + /* Dummy entry marking end of the array. */ |
| 111 | + {NULL, NULL} |
| 112 | +}; |
| 113 | + |
| 114 | +static bgworker_main_type GetInternalBgWorkerMain(BackgroundWorker *worker); |
| 115 | + |
96 | 116 | /*
|
97 | 117 | * Calculate shared memory needed.
|
98 | 118 | */
|
@@ -695,22 +715,27 @@ StartBackgroundWorker(void)
|
695 | 715 | #endif
|
696 | 716 | }
|
697 | 717 |
|
| 718 | + /* For internal workers set the entry point to known function address. */ |
| 719 | + entrypt = GetInternalBgWorkerMain(worker); |
| 720 | + |
698 | 721 | /*
|
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 |
| 722 | + * Otherwise, if bgw_main is set, we use that value as the initial |
| 723 | + * entrypoint. This does not work well EXEC_BACKEND outside Windows but |
| 724 | + * we keep the logic for backwards compatibility. In other cases use |
| 725 | + * the entry point specified by library name (which will be loaded, if |
| 726 | + * necessary) and a function name (which will be looked up in the named |
705 | 727 | * library).
|
706 | 728 | */
|
707 |
| - if (worker->bgw_main != NULL) |
708 |
| - entrypt = worker->bgw_main; |
709 |
| - else |
710 |
| - entrypt = (bgworker_main_type) |
711 |
| - load_external_function(worker->bgw_library_name, |
712 |
| - worker->bgw_function_name, |
713 |
| - true, NULL); |
| 729 | + if (entrypt == NULL) |
| 730 | + { |
| 731 | + if (worker->bgw_main != NULL) |
| 732 | + entrypt = worker->bgw_main; |
| 733 | + else |
| 734 | + entrypt = (bgworker_main_type) |
| 735 | + load_external_function(worker->bgw_library_name, |
| 736 | + worker->bgw_function_name, |
| 737 | + true, NULL); |
| 738 | + } |
714 | 739 |
|
715 | 740 | /*
|
716 | 741 | * Note that in normal processes, we would call InitPostgres here. For a
|
@@ -1050,3 +1075,28 @@ TerminateBackgroundWorker(BackgroundWorkerHandle *handle)
|
1050 | 1075 | if (signal_postmaster)
|
1051 | 1076 | SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);
|
1052 | 1077 | }
|
| 1078 | + |
| 1079 | +/* |
| 1080 | + * Search the known internal worker array and return its main function |
| 1081 | + * pointer if found. |
| 1082 | + * |
| 1083 | + * Returns NULL if not known internal worker. |
| 1084 | + */ |
| 1085 | +static bgworker_main_type |
| 1086 | +GetInternalBgWorkerMain(BackgroundWorker *worker) |
| 1087 | +{ |
| 1088 | + int i; |
| 1089 | + |
| 1090 | + /* Internal workers always have to use postgres as library name. */ |
| 1091 | + if (strncmp(worker->bgw_library_name, "postgres", BGW_MAXLEN) != 0) |
| 1092 | + return NULL; |
| 1093 | + |
| 1094 | + for (i = 0; InternalBGWorkers[i].bgw_function_name; i++) |
| 1095 | + { |
| 1096 | + if (strncmp(InternalBGWorkers[i].bgw_function_name, |
| 1097 | + worker->bgw_function_name, BGW_MAXLEN) == 0) |
| 1098 | + return InternalBGWorkers[i].bgw_main; |
| 1099 | + } |
| 1100 | + |
| 1101 | + return NULL; |
| 1102 | +} |
0 commit comments