| 2214 | } |
| 2215 | |
| 2216 | void checkChildrenDone(void) { |
| 2217 | int statloc = 0; |
| 2218 | pid_t pid; |
| 2219 | |
| 2220 | if (g_pserver->FRdbSaveInProgress() && !cserver.fForkBgSave) |
| 2221 | { |
| 2222 | void *rval = nullptr; |
| 2223 | int err = EAGAIN; |
| 2224 | if (!g_pserver->rdbThreadVars.fDone || (err = pthread_join(g_pserver->rdbThreadVars.rdb_child_thread, &rval))) |
| 2225 | { |
| 2226 | if (err != EBUSY && err != EAGAIN) |
| 2227 | serverLog(LL_WARNING, "Error joining the background RDB save thread: %s\n", strerror(errno)); |
| 2228 | } |
| 2229 | else |
| 2230 | { |
| 2231 | int exitcode = (int)reinterpret_cast<ptrdiff_t>(rval); |
| 2232 | backgroundSaveDoneHandler(exitcode,g_pserver->rdbThreadVars.fRdbThreadCancel); |
| 2233 | g_pserver->rdbThreadVars.fRdbThreadCancel = false; |
| 2234 | g_pserver->rdbThreadVars.fDone = false; |
| 2235 | if (exitcode == 0) receiveChildInfo(); |
| 2236 | closeChildInfoPipe(); |
| 2237 | } |
| 2238 | } |
| 2239 | else if ((pid = waitpid(-1, &statloc, WNOHANG)) != 0) { |
| 2240 | int exitcode = WIFEXITED(statloc) ? WEXITSTATUS(statloc) : -1; |
| 2241 | int bysignal = 0; |
| 2242 | |
| 2243 | if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc); |
| 2244 | |
| 2245 | /* sigKillChildHandler catches the signal and calls exit(), but we |
| 2246 | * must make sure not to flag lastbgsave_status, etc incorrectly. |
| 2247 | * We could directly terminate the child process via SIGUSR1 |
| 2248 | * without handling it */ |
| 2249 | if (exitcode == SERVER_CHILD_NOERROR_RETVAL) { |
| 2250 | bysignal = SIGUSR1; |
| 2251 | exitcode = 1; |
| 2252 | } |
| 2253 | |
| 2254 | if (pid == -1) { |
| 2255 | serverLog(LL_WARNING,"waitpid() returned an error: %s. " |
| 2256 | "child_type: %s, child_pid = %d", |
| 2257 | strerror(errno), |
| 2258 | strChildType(g_pserver->child_type), |
| 2259 | (int) g_pserver->child_pid); |
| 2260 | } else if (pid == g_pserver->child_pid) { |
| 2261 | if (g_pserver->child_type == CHILD_TYPE_RDB) { |
| 2262 | backgroundSaveDoneHandler(exitcode, bysignal); |
| 2263 | } else if (g_pserver->child_type == CHILD_TYPE_AOF) { |
| 2264 | backgroundRewriteDoneHandler(exitcode, bysignal); |
| 2265 | } else if (g_pserver->child_type == CHILD_TYPE_MODULE) { |
| 2266 | ModuleForkDoneHandler(exitcode, bysignal); |
| 2267 | } else { |
| 2268 | serverPanic("Unknown child type %d for child pid %d", g_pserver->child_type, g_pserver->child_pid); |
| 2269 | exit(1); |
| 2270 | } |
| 2271 | if (!bysignal && exitcode == 0) receiveChildInfo(); |
| 2272 | resetChildState(); |
| 2273 | } else { |
no test coverage detected