Esempio n. 1
0
/** finalize the context, if not already finalized */
static int ub_ctx_finalize(struct ub_ctx* ctx)
{
    int res = 0;
    lock_basic_lock(&ctx->cfglock);
    if (!ctx->finalized) {
        res = context_finalize(ctx);
    }
    lock_basic_unlock(&ctx->cfglock);
    return res;
}
Esempio n. 2
0
void writer_run(const reader_t* reader)
{
    context_t context;

    context_initialize(&context);

    calc_work(&context, reader);
    allocate_work(&context);
    read(&context, &reader);

    context_finalize(&context);
}
Esempio n. 3
0
int
ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
           int rrclass, struct ub_result** result)
{
    struct ctx_query* q;
    int r;
    *result = NULL;

    lock_basic_lock(&ctx->cfglock);
    if(!ctx->finalized) {
        r = context_finalize(ctx);
        if(r) {
            lock_basic_unlock(&ctx->cfglock);
            return r;
        }
    }
    /* create new ctx_query and attempt to add to the list */
    lock_basic_unlock(&ctx->cfglock);
    q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
    if(!q)
        return UB_NOMEM;
    /* become a resolver thread for a bit */

    r = libworker_fg(ctx, q);
    if(r) {
        lock_basic_lock(&ctx->cfglock);
        (void)rbtree_delete(&ctx->queries, q->node.key);
        context_query_delete(q);
        lock_basic_unlock(&ctx->cfglock);
        return r;
    }
    q->res->answer_packet = q->msg;
    q->res->answer_len = (int)q->msg_len;
    q->msg = NULL;
    *result = q->res;
    q->res = NULL;

    lock_basic_lock(&ctx->cfglock);
    (void)rbtree_delete(&ctx->queries, q->node.key);
    context_query_delete(q);
    lock_basic_unlock(&ctx->cfglock);
    return UB_NOERROR;
}
Esempio n. 4
0
int 
ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, 
	int rrclass, void* mydata, ub_event_callback_type callback,
	int* async_id)
{
	struct ctx_query* q;
	int r;

	if(async_id)
		*async_id = 0;
	lock_basic_lock(&ctx->cfglock);
	if(!ctx->finalized) {
		r = context_finalize(ctx);
		if(r) {
			lock_basic_unlock(&ctx->cfglock);
			return r;
		}
	}
	lock_basic_unlock(&ctx->cfglock);
	if(!ctx->event_worker) {
		ctx->event_worker = libworker_create_event(ctx,
			ctx->event_base);
		if(!ctx->event_worker) {
			return UB_INITFAIL;
		}
	}

	/* set time in case answer comes from cache */
	ub_comm_base_now(ctx->event_worker->base);

	/* create new ctx_query and attempt to add to the list */
	q = context_new(ctx, name, rrtype, rrclass, NULL, callback, mydata);
	if(!q)
		return UB_NOMEM;

	/* attach to mesh */
	if((r=libworker_attach_mesh(ctx, q, async_id)) != 0)
		return r;
	return UB_NOERROR;
}
Esempio n. 5
0
int
ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
                 int rrclass, void* mydata, ub_callback_t callback, int* async_id)
{
    struct ctx_query* q;
    uint8_t* msg = NULL;
    uint32_t len = 0;

    if(async_id)
        *async_id = 0;
    lock_basic_lock(&ctx->cfglock);
    if(!ctx->finalized) {
        int r = context_finalize(ctx);
        if(r) {
            lock_basic_unlock(&ctx->cfglock);
            return r;
        }
    }
    if(!ctx->created_bg) {
        int r;
        ctx->created_bg = 1;
        lock_basic_unlock(&ctx->cfglock);
        r = libworker_bg(ctx);
        if(r) {
            lock_basic_lock(&ctx->cfglock);
            ctx->created_bg = 0;
            lock_basic_unlock(&ctx->cfglock);
            return r;
        }
    } else {
        lock_basic_unlock(&ctx->cfglock);
    }

    /* create new ctx_query and attempt to add to the list */
    q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
    if(!q)
        return UB_NOMEM;

    /* write over pipe to background worker */
    lock_basic_lock(&ctx->cfglock);
    msg = context_serialize_new_query(q, &len);
    if(!msg) {
        (void)rbtree_delete(&ctx->queries, q->node.key);
        ctx->num_async--;
        context_query_delete(q);
        lock_basic_unlock(&ctx->cfglock);
        return UB_NOMEM;
    }
    if(async_id)
        *async_id = q->querynum;
    lock_basic_unlock(&ctx->cfglock);

    lock_basic_lock(&ctx->qqpipe_lock);
    if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) {
        lock_basic_unlock(&ctx->qqpipe_lock);
        free(msg);
        return UB_PIPE;
    }
    lock_basic_unlock(&ctx->qqpipe_lock);
    free(msg);
    return UB_NOERROR;
}