* Handle any queued protocol messages received from parallel workers. */
| 1060 | * Handle any queued protocol messages received from parallel workers. |
| 1061 | */ |
| 1062 | void |
| 1063 | HandleParallelMessages(void) |
| 1064 | { |
| 1065 | dlist_iter iter; |
| 1066 | MemoryContext oldcontext; |
| 1067 | |
| 1068 | static MemoryContext hpm_context = NULL; |
| 1069 | |
| 1070 | /* |
| 1071 | * This is invoked from ProcessInterrupts(), and since some of the |
| 1072 | * functions it calls contain CHECK_FOR_INTERRUPTS(), there is a potential |
| 1073 | * for recursive calls if more signals are received while this runs. It's |
| 1074 | * unclear that recursive entry would be safe, and it doesn't seem useful |
| 1075 | * even if it is safe, so let's block interrupts until done. |
| 1076 | */ |
| 1077 | HOLD_INTERRUPTS(); |
| 1078 | |
| 1079 | /* |
| 1080 | * Moreover, CurrentMemoryContext might be pointing almost anywhere. We |
| 1081 | * don't want to risk leaking data into long-lived contexts, so let's do |
| 1082 | * our work here in a private context that we can reset on each use. |
| 1083 | */ |
| 1084 | if (hpm_context == NULL) /* first time through? */ |
| 1085 | hpm_context = AllocSetContextCreate(TopMemoryContext, |
| 1086 | "HandleParallelMessages", |
| 1087 | ALLOCSET_DEFAULT_SIZES); |
| 1088 | else |
| 1089 | MemoryContextReset(hpm_context); |
| 1090 | |
| 1091 | oldcontext = MemoryContextSwitchTo(hpm_context); |
| 1092 | |
| 1093 | /* OK to process messages. Reset the flag saying there are more to do. */ |
| 1094 | ParallelMessagePending = false; |
| 1095 | |
| 1096 | dlist_foreach(iter, &pcxt_list) |
| 1097 | { |
| 1098 | ParallelContext *pcxt; |
| 1099 | int i; |
| 1100 | |
| 1101 | pcxt = dlist_container(ParallelContext, node, iter.cur); |
| 1102 | if (pcxt->worker == NULL) |
| 1103 | continue; |
| 1104 | |
| 1105 | for (i = 0; i < pcxt->nworkers_launched; ++i) |
| 1106 | { |
| 1107 | /* |
| 1108 | * Read as many messages as we can from each worker, but stop when |
| 1109 | * either (1) the worker's error queue goes away, which can happen |
| 1110 | * if we receive a Terminate message from the worker; or (2) no |
| 1111 | * more messages can be read from the worker without blocking. |
| 1112 | */ |
| 1113 | while (pcxt->worker[i].error_mqh != NULL) |
| 1114 | { |
| 1115 | shm_mq_result res; |
| 1116 | Size nbytes; |
| 1117 | void *data; |
| 1118 | |
| 1119 | res = shm_mq_receive(pcxt->worker[i].error_mqh, &nbytes, |
no test coverage detected