Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
	}
}
Esempio n. 3
0
/*
 * 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);
	}
}
Esempio n. 4
0
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 */
}
Esempio n. 5
0
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);
}