/* -------------------------------------------------------------------- * Push a response into the return queue and eventually tickle the * receiver. */ int send_blocking_resp_internal( blocking_child * c, blocking_pipe_header * resp ) { size_t qhead; int empty; /* >>>> ACCESS LOCKING STARTS >>>> */ wait_for_sem(c->accesslock, NULL); empty = ensure_workresp_empty_slot(c); qhead = c->head_response; c->responses[qhead % c->responses_alloc] = resp; c->head_response = 1 + qhead; tickle_sem(c->accesslock); /* <<<< ACCESS LOCKING ENDS <<<< */ /* queue consumer wake-up notification */ if (empty) { # ifdef WORK_PIPE write(c->resp_write_pipe, "", 1); # else tickle_sem(c->responses_pending); # endif } return 0; }
int send_blocking_req_internal( blocking_child * c, blocking_pipe_header * hdr, void * data ) { blocking_pipe_header * threadcopy; size_t payload_octets; REQUIRE(hdr != NULL); REQUIRE(data != NULL); DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); if (hdr->octets <= sizeof(*hdr)) return 1; /* failure */ payload_octets = hdr->octets - sizeof(*hdr); ensure_workitems_empty_slot(c); if (NULL == c->thread_ref) { ensure_workresp_empty_slot(c); start_blocking_thread(c); } threadcopy = emalloc(hdr->octets); memcpy(threadcopy, hdr, sizeof(*hdr)); memcpy((char *)threadcopy + sizeof(*hdr), data, payload_octets); return queue_req_pointer(c, threadcopy); }
int send_blocking_resp_internal( blocking_child * c, blocking_pipe_header * resp ) { ensure_workresp_empty_slot(c); c->responses[c->next_response] = resp; c->next_response = (1 + c->next_response) % c->responses_alloc; #ifdef USE_WORK_PIPE IGNORE(write(c->resp_write_pipe, "", 1)); #else sem_post(c->blocking_response_ready); #endif return 0; }