void process_blocking_resp( blocking_child * c ) { blocking_pipe_header * resp; void * data; #ifdef USE_WORK_THREAD do { #endif resp = receive_blocking_resp_internal(c); if (NULL != resp) { DEBUG_REQUIRE(BLOCKING_RESP_MAGIC == resp->magic_sig); data = (char *)resp + sizeof(*resp); intres_req_pending--; (*resp->done_func)(resp->rtype, resp->context, resp->octets - sizeof(*resp), data); free(resp); } #ifdef USE_WORK_THREAD } while (NULL != resp); #endif if (!worker_per_query && 0 == intres_req_pending) intres_timeout_req(CHILD_MAX_IDLE); else if (worker_per_query) req_child_exit(c); }
static void send_worker_home_atexit(void) { u_int idx; blocking_child * c; if (worker_process) return; for (idx = 0; idx < blocking_children_alloc; idx++) { c = blocking_children[idx]; if (NULL == c) continue; req_child_exit(c); } }
/* * worker_idle_timer_fired() * * The parent starts this timer when the last pending response has been * received from the child, making it idle, and clears the timer when a * request is dispatched to the child. Once the timer expires, the * child is sent packing. * * This is called when worker_idle_timer is nonzero and less than or * equal to current_time. */ void worker_idle_timer_fired(void) { u_int idx; blocking_child * c; DEBUG_REQUIRE(0 == intres_req_pending); intres_timeout_req(0); for (idx = 0; idx < blocking_children_alloc; idx++) { c = blocking_children[idx]; if (NULL == c) continue; req_child_exit(c); } }
int send_blocking_req_internal( blocking_child * c, blocking_pipe_header * hdr, void * data ) { int octets; int rc; DEBUG_REQUIRE(hdr != NULL); DEBUG_REQUIRE(data != NULL); DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); if (-1 == c->req_write_pipe) { fork_blocking_child(c); DEBUG_INSIST(-1 != c->req_write_pipe); } octets = sizeof(*hdr); rc = write(c->req_write_pipe, hdr, octets); if (rc == octets) { octets = hdr->octets - sizeof(*hdr); rc = write(c->req_write_pipe, data, octets); if (rc == octets) return 0; } if (rc < 0) msyslog(LOG_ERR, "send_blocking_req_internal: pipe write: %m"); else msyslog(LOG_ERR, "send_blocking_req_internal: short write %d of %d", rc, octets); /* Fatal error. Clean up the child process. */ req_child_exit(c); exit(1); /* otherwise would be return -1 */ }
void process_blocking_resp( blocking_child * c ) { blocking_pipe_header * resp; void * data; /* * On Windows send_blocking_resp_internal() may signal the * blocking_response_ready event multiple times while we're * processing a response, so always consume all available * responses before returning to test the event again. */ #ifdef WORK_THREAD do { #endif resp = receive_blocking_resp_internal(c); if (NULL != resp) { DEBUG_REQUIRE(BLOCKING_RESP_MAGIC == resp->magic_sig); data = (char *)resp + sizeof(*resp); intres_req_pending--; (*resp->done_func)(resp->rtype, resp->context, resp->octets - sizeof(*resp), data); free(resp); } #ifdef WORK_THREAD } while (NULL != resp); #endif if (!worker_per_query && 0 == intres_req_pending) intres_timeout_req(CHILD_MAX_IDLE); else if (worker_per_query) req_child_exit(c); }