int tube_write_msg(struct tube* tube, uint8_t* buf, uint32_t len, int ATTR_UNUSED(nonblock)) { uint8_t* a; verbose(VERB_ALGO, "tube write_msg len %d", (int)len); a = (uint8_t*)memdup(buf, len); if(!a) { log_err("out of memory in tube_write_msg"); return 0; } /* always nonblocking, this pipe cannot get full */ return tube_queue_item(tube, a, len); }
/** add result to the bg worker result queue */ static void add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt, int err, char* reason) { uint8_t* msg = NULL; uint32_t len = 0; if(w->want_quit) { context_query_delete(q); return; } /* serialize and delete unneeded q */ if(w->is_bg_thread) { lock_basic_lock(&w->ctx->cfglock); if(reason) q->res->why_bogus = strdup(reason); if(pkt) { q->msg_len = sldns_buffer_remaining(pkt); q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len); if(!q->msg) msg = context_serialize_answer(q, UB_NOMEM, NULL, &len); else msg = context_serialize_answer(q, err, NULL, &len); } else msg = context_serialize_answer(q, err, NULL, &len); lock_basic_unlock(&w->ctx->cfglock); } else { if(reason) q->res->why_bogus = strdup(reason); msg = context_serialize_answer(q, err, pkt, &len); (void)rbtree_delete(&w->ctx->queries, q->node.key); w->ctx->num_async--; context_query_delete(q); } if(!msg) { log_err("out of memory for async answer"); return; } if(!tube_queue_item(w->ctx->rr_pipe, msg, len)) { log_err("out of memory for async answer"); return; } }