static void cmdOperation(master_t *master, risp_length_t length, void *data) { risp_length_t processed; risp_length_t plen; risp_data_t *pdata; int cnt; assert(master); assert(length > 0); assert(data); // we have data, that we need to put through the risp_op parser. It will // return some transaction details, and a payload. assert(master->risp_op); risp_clear_all(master->risp_op); processed = risp_process(master->risp_op, NULL, length, data); assert(processed == length); // if ( risp_isset(storage->risp_op, STASH_CMD_USER_ID) != 0) { // storage->opdata.user_id = risp_getvalue(storage->risp_op, STASH_CMD_USER_ID); // } // if ( risp_isset(storage->risp_op, STASH_CMD_DATE) != 0) { // storage->opdata.date = risp_getvalue(storage->risp_op, STASH_CMD_DATE); // } // if ( risp_isset(storage->risp_op, STASH_CMD_TIME) != 0) { // storage->opdata.time = risp_getvalue(storage->risp_op, STASH_CMD_TIME); // } assert ( risp_isset(master->risp_op, STASH_CMD_PAYLOAD) != 0); plen = risp_getlength(master->risp_op, STASH_CMD_PAYLOAD); pdata = risp_getdata(master->risp_op, STASH_CMD_PAYLOAD); assert(pdata); assert(plen > 0); // now that we have everything setup ready to process the information, we // need to parse the payload. THe payload RISP interface will have // callbacks for all the operational commands, so whatever needs to be // done will be handled internally. When the parse function has finished, // there is nothing else for us to do. risp_clear_all(master->risp_payload); processed = risp_process(master->risp_payload, master, plen, pdata); assert(processed == plen); // need to somehow identify if the payload is something other than what we // expect so that we can report that there is at least something there. for (cnt=0; cnt<256; cnt++) { if (master->risp_payload->commands[cnt].handler == NULL) { if (master->risp_payload->commands[cnt].set) { printf("Unexpected operation: %d\n", cnt); } } } }
static void cmdCreateNamespace(master_t *master, risp_length_t length, void *data) { char *newuser; nsid_t id; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE) != 0); assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID) != 0); newuser = risp_getstring(master->risp_data, STASH_CMD_NAMESPACE); id = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(newuser); assert(id > 0); printf("New Namespace: [nsid:%d]='%s'\n", id, newuser); }
static void cmdDelete(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; rowid_t rid = 0; keyid_t kid = 0; risp_length_t processed; assert(master && length > 0 && data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_ROW_ID)); rid = risp_getvalue(master->risp_data, STASH_CMD_ROW_ID); assert(rid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); if(risp_isset(master->risp_data, STASH_CMD_KEY_ID)) { kid = risp_getvalue(master->risp_data, STASH_CMD_KEY_ID); assert(kid > 0); } printf("Delete: [nsid:%d, tid:%d, rid:%d, kid:%d]\n", nsid, tid, rid, kid); }
static void cmdCreateRow(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; nameid_t nid = 0; rowid_t rid = 0; risp_length_t processed; assert(master && length > 0 && data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_ROW_ID)); rid = risp_getvalue(master->risp_data, STASH_CMD_ROW_ID); assert(rid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAME_ID)); nid = risp_getvalue(master->risp_data, STASH_CMD_NAME_ID); assert(nid > 0); printf("Create Row: [nsid:%d, tid:%d, nid:%d, rid:%d]\n", nsid, tid, nid, rid); }
static void cmdCreateUser(master_t *master, risp_length_t length, void *data) { char *newuser; userid_t uid; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_USERNAME) != 0); assert(risp_isset(master->risp_data, STASH_CMD_USER_ID) != 0); newuser = risp_getstring(master->risp_data, STASH_CMD_USERNAME); uid = risp_getvalue(master->risp_data, STASH_CMD_USER_ID); assert(newuser); assert(uid > 0); printf("New User: [uid:%d]='%s'\n", uid, newuser); }
//----------------------------------------------------------------------------- // This callback function is used when a complete message is received to // consume. We basically need to create a request to handle it, add it to the // list. If a reply is sent during the processing, then it will close out the // request automatically, otherwise it will be up to something else to close it // out. static void message_handler(rq_message_t *msg, void *arg) { int processed; rq_http_t *http; rq_http_req_t *req; assert(msg); assert(arg); http = (rq_http_t *) arg; assert(http); // We dont know what the use of this object will be, so we need to create it // and put it in a list (to keep track of it) until something gets rid of it. req = req_new(http, http->arg); req->msg = msg; assert(req->reply); assert(BUF_LENGTH(req->reply) == 0); assert(msg->data); assert(http->risp); processed = risp_process(http->risp, req, BUF_LENGTH(msg->data), BUF_DATA(msg->data)); assert(processed == BUF_LENGTH(msg->data)); // if we still have the msg pointer as part of the request, then the message // hasn't been replied yet, so we need to add the request to the list and // let it finish elsewhere. if (req->msg) { assert(req->inprocess == 0); req->inprocess++; // then we need to add this request to the list. assert(http->req_list); ll_push_head(http->req_list, req); req = NULL; } else { // We have already replied to the request, so we dont need it anymore. req_free(req); req = NULL; } }
//----------------------------------------------------------------------------- // Handle the response from the blacklist service. static void blacklist_handler(rq_message_t *reply) { cache_waiting_t *waiting; int processed; assert(reply); waiting = reply->arg; assert(waiting); assert(waiting->msg == NULL); waiting->msg = reply; assert(reply->data); assert(waiting->blacklist); assert(waiting->blacklist->risp); processed = risp_process(waiting->blacklist->risp, waiting, BUF_LENGTH(reply->data), (risp_char_t *) BUF_DATA(reply->data)); assert(processed == BUF_LENGTH(reply->data)); waiting->msg = NULL; }
//----------------------------------------------------------------------------- // Handle the message that was sent over the queue. the message itself uses // the RISP method, so we pass the data on to the risp processor. static void message_handler(rq_message_t *msg, void *arg) { int processed; control_t *control; assert(msg); control = (control_t *) arg; assert(control); assert(control->rqsvc); assert(control->rqsvc->rq); assert(msg->conn); assert(msg->conn->rq); assert(control->rqsvc->rq == msg->conn->rq); assert(control->reply); assert(BUF_LENGTH(control->reply) == 0); // since we will only be processing one request at a time, and there are no // paths for blocking when processing the request, we will put the request // in the control structure. If we were processing more than one, we would // create a list of pending requests which contain the control structure in // it. assert(control->req == NULL); control->req = msg; assert(control->risp); assert(msg->data); processed = risp_process(control->risp, control, BUF_LENGTH(msg->data), BUF_DATA(msg->data)); assert(processed == BUF_LENGTH(msg->data)); // we need to get the reply and return it. Has that been done? assert(control->reply); assert(BUF_LENGTH(control->reply) > 0); rq_reply(msg, BUF_LENGTH(control->reply), BUF_DATA(control->reply)); expbuf_clear(control->reply); msg = NULL; control->req = NULL; }
static void cmdSet(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; rowid_t rid = 0; keyid_t kid = 0; risp_length_t val_len; risp_length_t processed; assert(master && length > 0 && data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_ROW_ID)); rid = risp_getvalue(master->risp_data, STASH_CMD_ROW_ID); assert(rid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); assert(risp_isset(master->risp_data, STASH_CMD_KEY_ID)); kid = risp_getvalue(master->risp_data, STASH_CMD_KEY_ID); assert(kid > 0); assert(risp_isset(master->risp_data, STASH_CMD_VALUE)); val_len = risp_getlength(master->risp_data, STASH_CMD_VALUE); assert(val_len > 0); printf("Set Attribute: [nsid:%d, tid:%d, rid:%d, kid:%d, val-len:%d]\n", nsid, tid, rid, kid, val_len); }
static void cmdSetPassword(master_t *master, risp_length_t length, void *data) { userid_t id; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); assert(risp_isset(master->risp_data, STASH_CMD_PASSWORD) != 0); assert(risp_isset(master->risp_data, STASH_CMD_USER_ID) != 0); id = risp_getvalue(master->risp_data, STASH_CMD_USER_ID); assert(id > 0); printf("Password set: [uid:%d]\n", id); }
static void cmdCreateTable(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; char *tablename; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); // if we have a namespace, get it. assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE)); tablename = risp_getstring(master->risp_data, STASH_CMD_TABLE); assert(tablename); printf("Create Table: [nsid:%d, tid:%d] '%s'", nsid, tid, tablename); if (risp_isset(master->risp_data, STASH_CMD_STRICT) != 0) { printf(" STRICT"); } if (risp_isset(master->risp_data, STASH_CMD_UNIQUE) != 0) { printf(" UNIQUE"); } if (risp_isset(master->risp_data, STASH_CMD_OVERWRITE) != 0) { printf(" OVERWRITE"); } printf("\n"); }
static void cmdCreateKey(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; keyid_t kid = 0; char *keyname; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); // if we have a namespace, get it. assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); assert(risp_isset(master->risp_data, STASH_CMD_KEY_ID)); kid = risp_getvalue(master->risp_data, STASH_CMD_KEY_ID); assert(kid > 0); assert(risp_isset(master->risp_data, STASH_CMD_KEY)); keyname = risp_getstring(master->risp_data, STASH_CMD_KEY); assert(keyname); printf("Create Key: [nsid:%d, tid:%d, kid:%d] '%s'\n", nsid, tid, kid, keyname); }
static void cmdCreateName(master_t *master, risp_length_t length, void *data) { nsid_t nsid = 0; tableid_t tid = 0; nameid_t nid = 0; char *rowname; risp_length_t processed; assert(master && length > 0 && data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); // if we have a namespace, get it. assert(risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID)); nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); assert(risp_isset(master->risp_data, STASH_CMD_TABLE_ID)); tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAME_ID)); nid = risp_getvalue(master->risp_data, STASH_CMD_NAME_ID); assert(nid > 0); assert(risp_isset(master->risp_data, STASH_CMD_NAME)); rowname = risp_getstring(master->risp_data, STASH_CMD_NAME); assert(rowname); printf("Create Name: [nsid:%d, tid:%d, nid:%d] '%s'\n", nsid, tid, nid, rowname); }
int main(int argc, char **argv) { // parameters that are provided. char *srv = "127.0.0.1"; int port = DEFAULT_PORT; // this data object will be passed to all the callback routines. Initialise it. data_t data; data.handle = -1; data.msg_id = 0; data.latest_msg_id = 0; data.name = NULL; // get the command line options. int c; while ((c = getopt(argc, argv, "p:s:h")) != -1) { switch (c) { case 'p': port = atoi(optarg); assert(port > 0); break; case 's': srv = strdup(optarg); assert(srv != NULL); break; case 'h': printf("usage:\n\nrisp_chat_stream2 [-s server] [-p port] [-h]\n"); exit(1); break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } // set the signal trap, so we can break out of the loop when user presses Ctrl-C. signal(SIGINT, sig_handler); // get an initialised risp structure. RISP_PTR risp = risp_init(); assert(risp); // add the callback routines for the commands we are going to receive. risp_add_command(risp, CMD_NOP, &cmdNop); risp_add_command(risp, CMD_HELLO_ACK, &cmdHelloAck); risp_add_command(risp, CMD_MSG_ID, &cmdMsgID); risp_add_command(risp, CMD_LATEST_MSG_ID, &cmdLatestMsgID); risp_add_command(risp, CMD_NAME, &cmdName); risp_add_command(risp, CMD_MESSAGE, &cmdMessage); risp_add_invalid(risp, &cmdInvalid); // connect to the remote socket. We will leave it in blocking mode. When we do the recv, we // will specify that the recv operation is non-blocking. assert(srv && port > 0); data.handle = sock_connect(srv, port); if (data.handle <= 0) { printf("Unable to connect to %s:%d\n", srv, port); } else { // now that we are connected, first we need to send the HELLO and NO_FOLLOW commands. // These commands could have been lumped together in a single send, but for the purpose of // demonstrating RISP, this code does each operationg specifically. if (sendInit(data.handle) != 0) { // couldn't send the command, close the handle, and exit. close(data.handle); data.handle = -1; } // setup the initial buffer. Since we dont really know how much data we will receive from // the server, we will grow the buffer as needed. int max = 0; char *buffer = NULL; int used = 0; int goodbye_sent = 0; // if we have sent a GOODBYE, we dont want to // we will loop until the socket is closed. If the user presses Ctrl-C, we will send a // GOODBYE command to the server, which will then close the socket. If the user presses // Ctrl-C more than once, we will not wait for the server, and will close the socket // directly. Every time the user presses Ctrl-C, it should break out of the sleep, so it // should respond pretty quickly. while (data.handle >= 0) { // printf("."); assert(used <= max); if (max-used < CHUNK_SIZE) { max += CHUNK_SIZE; buffer = realloc(buffer, max); assert(buffer); // fprintf(stderr, "Increased Max Buffer to %d\n", max); } // check for data on the socket. We will do the receive in non-blocking mode, so if // there is no data, it will return immediately. If we received no data, we will wait for // 1 second before trying again. If we have waited for 5 seconds, then we need to // send a NOP to keep the connection alive. char *ptr = buffer + used; int avail = max - used; // fprintf(stderr, "About to recv. avail=%d\n", avail); int result = recv(data.handle, ptr, avail, MSG_DONTWAIT); // printf("Recv: result=%d, used=%d, max=%d\n", result, used, max); if (result < 0) { assert(result == -1); if (errno == EWOULDBLOCK || errno == EAGAIN) { // there was no data to read from the socket. // we will now sleep for 1 second. If the user pressed Ctrl-C, then the sleep // function will exit immediately. Only do the sleep if Ctrl-C hasn't been hit. if (_sigtrap == 0) { sleep(1); } } else { fprintf(stderr, "Unexpected result received from socket. errno=%d '%s'\n", errno, strerror(errno)); } } else if (result == 0) { // socket has closed. close(data.handle); data.handle = -1; } else { assert(result > 0); assert(result <= avail); assert(used >= 0); used += result; assert(used <= max); // if we have some data received, then we need to process it. // fprintf(stderr, "Processing: %d\n", used); risp_length_t processed = risp_process(risp, &data, used, buffer); // fprintf(stderr, "Processed: %ld\n", processed); assert(processed >= 0); assert(processed <= used); if (processed < used) { // Our commands have probably been fragmented. // fprintf(stderr, "Fragmented commands: processed=%ld, used=%d, max=%d\n", processed, used, max); fflush(stdout); if (processed > 0) { // we need to remove from the buffer the data that we have processed. // This is a simple approach, but not the most efficient. assert(sizeof(*buffer) == 1); char *ptr = buffer+processed; size_t length = used-processed; assert((processed + length) == used); // fprintf(stderr, "Moving data. length=%ld\n", length); memmove(buffer, ptr, length); used -= processed; assert(used > 0); assert(used < max); // fprintf(stderr, "After move. used=%d, max=%d\n", used, max); } } else { used = 0; } assert(used >= 0 && used <= max); } if (data.handle >= 0) { if (_sigtrap == 1 && goodbye_sent == 0) { fprintf(stderr, "Closing...\n"); // TODO: shouldn't just close the socket. Should instead send GOODBYE command and wait for socket to close. if (sendGoodbye(data.handle) != 0) { close(data.handle); data.handle = -1; } goodbye_sent ++; } else if (_sigtrap > 1) { close(data.handle); data.handle = -1; } } } } // clean up the risp structure. risp_shutdown(risp); risp = NULL; return 0; }
int main(int argc, char **argv) { int c; risp_t *risp; int sent; char *srv = "127.0.0.1"; char *filename = NULL; int port = DEFAULT_PORT; int avail; int processed; int len; int done = 0, t; node_t node; // initialise the node data. node.handle = INVALID_HANDLE; node.verbose = 0; node.finished = 0; expbuf_init(&node.in, 1024); expbuf_init(&node.out, 1024); expbuf_init(&node.data.file, 0); expbuf_init(&node.data.data, 0); node.data.op = CMD_NOP; node.data.size = 0; node.data.offset = 0; node.filehandle = INVALID_HANDLE; node.size = 0; node.offset = 0; while ((c = getopt(argc, argv, "f:p:s:v")) != -1) { switch (c) { case 'f': filename = optarg; assert(filename != NULL); break; case 'p': port = atoi(optarg); assert(port > 0); break; case 's': srv = optarg; assert(srv != NULL); break; case 'v': node.verbose ++; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } if (filename == NULL) { fprintf(stderr, "Need a filename.\n\n"); exit(1); } // get an initialised risp structure. risp = risp_init(); if (risp == NULL) { printf("Unable to initialise RISP library.\n"); } else { risp_add_command(risp, CMD_CLEAR, &cmdClear); risp_add_command(risp, CMD_EXECUTE, &cmdExecute); risp_add_command(risp, CMD_OFFSET, &cmdOffset); risp_add_command(risp, CMD_SIZE, &cmdSize); risp_add_command(risp, CMD_FILE, &cmdFile); risp_add_command(risp, CMD_DATA, &cmdData); risp_add_command(risp, CMD_PUT, &cmdPut); risp_add_command(risp, CMD_GET, &cmdGet); len = strlen(filename); assert(len < 256); assert(node.out.length == 0); addCmd(&node.out, CMD_CLEAR); addCmd(&node.out, CMD_GET); addCmdShortStr(&node.out, CMD_FILE, len, filename); addCmd(&node.out, CMD_EXECUTE); // and process it a lot of time. printf("Sending request for: %s\n", filename); // connect to the remote socket. node.handle = sock_connect(srv, port); if (node.handle <= 0) { printf("Unable to connect to %s:%d\n", srv, port); } else { while (sigtrap == 0 && node.finished == 0) { // continue to send data to the socket over and over as quickly as possible. while (node.out.length > 0) { assert(node.handle > 0); sent = sock_send(node.handle, node.out.data, node.out.length); if (sent < 0) { sigtrap ++; } else { assert(sent > 0); assert(sent <= node.out.length); if (sent == node.out.length) { expbuf_clear(&node.out); } else { expbuf_purge(&node.out, sent); } } } // if we didn't generate a fail during the write, then we do a read. if (sigtrap == 0) { avail = node.in.max - node.in.length; if (avail < 1024) { expbuf_shrink(&node.in, 1024); avail = 1024; } sent = sock_receive(node.handle, node.in.data + node.in.length, avail); if (sent < 0) { sigtrap ++; } else { assert(sent > 0); node.in.length += sent; assert(node.in.length <= node.in.max); if (sent == avail) { // we filled the incoming buffer, so we need to double it. expbuf_shrink(&node.in, node.in.max * 2); } processed = risp_process(risp, &node, node.in.length, (unsigned char *) node.in.data); // printf("Processed %d.\n", processed); if (processed > 0) { expbuf_purge(&node.in, processed); if (node.offset > 0 && node.size > 0) { t = (node.offset / (node.size/100)); if (t > done) { done = t; printf("Done - %c%d\n", '%', done); } } } } } } // close the socket. if (node.handle >= 0) { close(node.handle); } } // clean up the risp structure. risp_shutdown(risp); } return 0; }
// this function is called when we have received a new socket. We need to // create a new node, and add it to our node list. We need to pass to the node // any pointers to other sub-systems that it will need to have, and then we // insert the node into the 'node-circle' somewhere. Finally, we need to add // the new node to the event base. static void node_event_handler(int hid, short flags, void *data) { node_t *node; unsigned int avail; int res; assert(hid >= 0); node = (node_t *) data; assert(node != NULL); assert(node->handle == hid); assert(node->stats != NULL); assert(node->active == true); assert(node->event.ev_base != NULL); if (flags & EV_READ) { assert(node->in.max >= DEFAULT_BUFFSIZE); avail = node->in.max - node->in.length; if (avail < DEFAULT_BUFFSIZE) { // we dont have much space left in the buffer, lets double its size. expbuf_shrink(&node->in, node->in.max * 2); avail = node->in.max - node->in.length; } // for performance reasons, we will read the data in directly into the expanding buffer. assert(avail >= DEFAULT_BUFFSIZE); node->stats->reads++; res = read(hid, node->in.data+node->in.length, avail); if (res > 0) { node->stats->in_bytes += res; node->in.length += res; assert(node->in.length <= node->in.max); // if we pulled out the max we had avail in our buffer, that means we can pull out more at a time. if (res == avail) { expbuf_shrink(&node->in, node->in.max * 2); } assert(node->active); if (node->in.length > 0) { assert(node->risp != NULL); node->stats->cycles ++; res = risp_process(node->risp, node, node->in.length, (unsigned char *) node->in.data); assert(res <= node->in.length); assert(res >= 0); if (res < node->in.length) { node->stats->undone += (node->in.length - res); } if (res > 0) { expbuf_purge(&node->in, res); } } } else if (res == 0) { node->handle = INVALID_HANDLE; if (node->filehandle != INVALID_HANDLE) { close(node->filehandle); node->filehandle = INVALID_HANDLE; } node_clear(node); assert(node->active == false); printf("Node[%d] closed while reading.\n", hid); } else { assert(res == -1); if (errno != EAGAIN && errno != EWOULDBLOCK) { close(node->handle); node->handle = INVALID_HANDLE; if (node->filehandle != INVALID_HANDLE) { close(node->filehandle); node->filehandle = INVALID_HANDLE; } node_clear(node); assert(node->active == false); printf("Node[%d] closed while reading- because of error: %d\n", hid, errno); } } } if (flags & EV_WRITE && node->active) { // we've requested the event, so we should have data to process. assert(node->out.length > 0); assert(node->out.length <= node->out.max); node->stats->writes ++; res = send(hid, node->out.data, node->out.length, 0); if (res > 0) { // we managed to send some, or maybe all.... assert(res <= node->out.length); node->stats->out_bytes += res; expbuf_purge(&node->out, res); // if we are in the process of transmitting a file, then we need // to get more file data and put in the buffer, since we depleted // some of it. if (node->sending) { sendFileData(node); } } else if (res == 0) { node->handle = INVALID_HANDLE; if (node->filehandle != INVALID_HANDLE) { close(node->filehandle); node->filehandle = INVALID_HANDLE; } node_clear(node); assert(node->active == false); printf("Node[%d] closed while writing.\n", hid); } else { assert(res == -1); if (errno != EAGAIN && errno != EWOULDBLOCK) { close(node->handle); node->handle = INVALID_HANDLE; if (node->filehandle != INVALID_HANDLE) { close(node->filehandle); node->filehandle = INVALID_HANDLE; } node_clear(node); assert(node->active == false); printf("Node[%d] closed while writing - because of error: %d\n", hid, errno); } } // if we have sent everything, then we dont need to wait for a WRITE event anymore, so we need to re-establish the events. if (node->active && node->out.length == 0) { if (event_del(&node->event) != -1) { event_set(&node->event, hid, EV_READ | EV_PERSIST, node_event_handler, (void *)node); event_base_set(node->event.ev_base, &node->event); event_add(&node->event, 0); } } } }
static void cmdGrant(master_t *master, risp_length_t length, void *data) { userid_t uid = 0; nsid_t nsid = 0; tableid_t tid = 0; risp_length_t processed; assert(master); assert(length > 0); assert(data); assert(master->risp_data); risp_clear_all(master->risp_data); processed = risp_process(master->risp_data, NULL, length, data); assert(processed == length); // get the userid. assert(risp_isset(master->risp_data, STASH_CMD_USER_ID) != 0); uid = risp_getvalue(master->risp_data, STASH_CMD_USER_ID); assert(uid > 0); // if we have a namespace, get it. if (risp_isset(master->risp_data, STASH_CMD_NAMESPACE_ID) != 0) { nsid = risp_getvalue(master->risp_data, STASH_CMD_NAMESPACE_ID); assert(nsid > 0); if (risp_isset(master->risp_data, STASH_CMD_TABLE_ID) != 0) { tid = risp_getvalue(master->risp_data, STASH_CMD_TABLE_ID); assert(tid > 0); printf("Grant: [uid:%d, nsid:%d, tid:%d]", uid, nsid, tid); } else { printf("Grant: [uid:%d, nsid:%d]", uid, nsid); } } else { printf("Grant: [uid:%d]", uid); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_ADDUSER) != 0) { printf(" ADDUSER"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_CREATE) != 0) { printf(" CREATE"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_DROP) != 0) { printf(" DROP"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_SET) != 0) { printf(" SET"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_UPDATE) != 0) { printf(" UPDATE"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_DELETE) != 0) { printf(" DELETE"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_QUERY) != 0) { printf(" QUERY"); } if (risp_isset(master->risp_data, STASH_CMD_RIGHT_LOCK) != 0) { printf(" LOCK"); } printf("\n"); }