void tube_handle_signal(int ATTR_UNUSED(fd), short ATTR_UNUSED(events), void* arg) { struct tube* tube = (struct tube*)arg; uint8_t* buf; uint32_t len = 0; verbose(VERB_ALGO, "tube handle_signal"); while(tube_poll(tube)) { if(tube_read_msg(tube, &buf, &len, 1)) { fptr_ok(fptr_whitelist_tube_listen(tube->listen_cb)); (*tube->listen_cb)(tube, buf, len, NETEVENT_NOERROR, tube->listen_arg); } } }
int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len, int nonblock) { struct tube_res_list* item = NULL; verbose(VERB_ALGO, "tube read_msg %s", nonblock?"nonblock":"blocking"); *buf = NULL; if(!tube_poll(tube)) { verbose(VERB_ALGO, "tube read_msg nodata"); /* nothing ready right now, wait if we want to */ if(nonblock) return -1; /* would block waiting for items */ if(!tube_wait(tube)) return 0; } lock_basic_lock(&tube->res_lock); if(tube->res_list) { item = tube->res_list; tube->res_list = item->next; if(tube->res_last == item) { /* the list is now empty */ tube->res_last = NULL; verbose(VERB_ALGO, "tube read_msg lastdata"); if(!WSAResetEvent(tube->event)) { log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError())); } } } lock_basic_unlock(&tube->res_lock); if(!item) return 0; /* would block waiting for items */ *buf = item->buf; *len = item->len; free(item); verbose(VERB_ALGO, "tube read_msg len %d", (int)*len); return 1; }
int ub_poll(struct ub_ctx* ctx) { /* no need to hold lock while testing for readability. */ return tube_poll(ctx->rr_pipe); }