예제 #1
0
static void
chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
{
    const lcb_RESPHTTP *rh = (const lcb_RESPHTTP *)rb;
    N1QLREQ *req = rh->cookie;

    (void)ign; (void)instance;

    req->cur_htresp = rh;
    if (rh->rc != LCB_SUCCESS || rh->htstatus != 200) {
        if (req->lasterr == LCB_SUCCESS || rh->htstatus != 200) {
            req->lasterr = rh->rc ? rh->rc : LCB_HTTP_ERROR;
        }
    }

    if (rh->rflags & LCB_RESP_F_FINAL) {
        req->htreq = NULL;
        destroy_req(req);
        return;
    } else if (req->callback == NULL) {
        /* Cancelled. Similar to the block above, except the http request
         * should remain alive (so we can cancel it later on) */
        destroy_req(req);
        return;
    }

    lcbjsp_feed(req->parser, rh->body, rh->nbody);
}
예제 #2
0
static int find_interrupted(struct fuse_ll *f, struct fuse_req *req)
{
    struct fuse_req *curr;

    for (curr = f->list.next; curr != &f->list; curr = curr->next) {
        if (curr->unique == req->u.i.unique) {
            curr->ctr++;
            pthread_mutex_unlock(&f->lock);

            /* Ugh, ugly locking */
            pthread_mutex_lock(&curr->lock);
            pthread_mutex_lock(&f->lock);
            curr->interrupted = 1;
            pthread_mutex_unlock(&f->lock);
            if (curr->u.ni.func)
                curr->u.ni.func(curr, curr->u.ni.data);
            pthread_mutex_unlock(&curr->lock);

            pthread_mutex_lock(&f->lock);
            curr->ctr--;
            if (!curr->ctr)
                destroy_req(curr);

            return 1;
        }
    }
    for (curr = f->interrupts.next; curr != &f->interrupts;
         curr = curr->next) {
        if (curr->u.i.unique == req->u.i.unique)
            return 1;
    }
    return 0;
}
예제 #3
0
void fuse_free_req(fuse_req_t req)
{
	int ctr;
	struct fuse_ll *f = req->f;

	pthread_mutex_lock(&f->lock);
	req->u.ni.func = NULL;
	req->u.ni.data = NULL;
	list_del_req(req);
	ctr = --req->ctr;
	pthread_mutex_unlock(&f->lock);
	if (!ctr)
		destroy_req(req);
}
예제 #4
0
static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
    struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
    struct fuse_ll *f = req->f;

    (void) nodeid;
    if (f->debug)
        fprintf(stderr, "INTERRUPT: %llu\n", (unsigned long long) arg->unique);

    req->u.i.unique = arg->unique;

    pthread_mutex_lock(&f->lock);
    if (find_interrupted(f, req))
        destroy_req(req);
    else
        list_add_req(req, &f->interrupts);
    pthread_mutex_unlock(&f->lock);
}
예제 #5
0
static int perform_query_cmd(req_t *req)
{
/*  Performs the QUERY command, returning a list of consoles that
 *    matches the console patterns given in the client's request.
 *  Returns 0 if the command succeeds, or -1 on error.
 *  Since this cmd is processed entirely by this thread,
 *    the client socket connection is closed once it is finished.
 */
    assert(req->sd >= 0);
    assert(req->command == CONMAN_CMD_QUERY);
    assert(!list_is_empty(req->consoles));

    log_msg(LOG_INFO, "Client <%s@%s:%d> issued query command",
        req->user, req->fqdn, req->port);

    if (send_rsp(req, CONMAN_ERR_NONE, NULL) < 0)
        return(-1);
    destroy_req(req);
    return(0);
}
예제 #6
0
LIBCOUCHBASE_API
lcb_error_t
lcb_n1ql_query(lcb_t instance, const void *cookie, const lcb_CMDN1QL *cmd)
{
    lcb_CMDHTTP htcmd = { 0 };
    lcb_error_t err;
    N1QLREQ *req = NULL;

    if (cmd->query == NULL || cmd->nquery == 0 ||
            cmd->callback == NULL || cmd->content_type == NULL) {
        return LCB_EINVAL;
    }
    htcmd.body = cmd->query;
    htcmd.nbody = cmd->nquery;
    htcmd.content_type = cmd->content_type;
    htcmd.method = LCB_HTTP_METHOD_POST;
    if (cmd->host) {
        htcmd.type = LCB_HTTP_TYPE_RAW;
        LCB_CMD_SET_KEY(&htcmd, QUERY_PATH, strlen(QUERY_PATH));
        htcmd.host = cmd->host;
        htcmd.username = LCBT_SETTING(instance, bucket);
        htcmd.password = LCBT_SETTING(instance, password);
    } else {
        htcmd.type = LCB_HTTP_TYPE_N1QL;
    }

    htcmd.cmdflags = LCB_CMDHTTP_F_STREAM;
    req = calloc(1, sizeof(*req));
    if (!req) {
        err = LCB_CLIENT_ENOMEM; goto GT_DESTROY;
    }

    req->callback = cmd->callback;
    req->cookie = cookie;
    req->instance = instance;
    req->parser = lcbjsp_create(LCBJSP_MODE_N1QL);

    if (!req->parser) {
        err = LCB_CLIENT_ENOMEM; goto GT_DESTROY;
    }
    req->parser->data = req;
    req->parser->callback = row_callback;

    htcmd.reqhandle = &req->htreq;
    err = lcb_http3(instance, req, &htcmd);
    if (err != LCB_SUCCESS) {
        goto GT_DESTROY;
    }

    lcb_htreq_setcb(req->htreq, chunk_callback);
    if (cmd->handle) {
        *cmd->handle = req;
    }
    return LCB_SUCCESS;

    GT_DESTROY:
    if (req) {
        req->callback = NULL;
        destroy_req(req);
    }
    return err;
}
예제 #7
0
void process_client(client_arg_t *args)
{
/*  The thread responsible for accepting a client connection
 *    and processing the request.
 *  The QUERY cmd is processed entirely by this thread.
 *  The MONITOR and CONNECT cmds are setup and then placed
 *    in the conf->objs list to be handled by mux_io().
 */
    int sd;
    server_conf_t *conf;
    req_t *req;

    /*  Free the tmp struct that was created by accept_client()
     *    in order to pass multiple args to this thread.
     */
    assert(args != NULL);
    sd = args->sd;
    conf = args->conf;
    free(args);

    DPRINTF((5, "Processing new client.\n"));

    x_pthread_detach(pthread_self());

    req = create_req();

    if (resolve_addr(conf, req, sd) < 0)
        goto err;
    if (recv_greeting(req) < 0)
        goto err;
    if (recv_req(req) < 0)
        goto err;
    if (query_consoles(conf, req) < 0)
        goto err;
    if (validate_req(req) < 0)
        goto err;

    /*  send_rsp() needs to know if the reset command is supported.
     *    Since it cannot check resetCmd in the server_conf struct,
     *    we set a flag in the request struct instead.
     */
    if (conf->resetCmd)
        req->enableReset = 1;

    switch(req->command) {
    case CONMAN_CMD_CONNECT:
        if (perform_connect_cmd(req, conf) < 0)
            goto err;
        break;
    case CONMAN_CMD_MONITOR:
        if (perform_monitor_cmd(req, conf) < 0)
            goto err;
        break;
    case CONMAN_CMD_QUERY:
        if (perform_query_cmd(req) < 0)
            goto err;
        break;
    default:
        log_msg(LOG_WARNING, "Received invalid command=%d from <%s@%s:%d>",
            req->command, req->user, req->fqdn, req->port);
        goto err;
    }
    return;

err:
    destroy_req(req);
    return;
}