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); }
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; }
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); }
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); }
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); }
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; }
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; }