From: Trond Norbye Date: Mon, 5 Oct 2009 21:00:48 +0000 (+0200) Subject: Update protocol due to review comments: X-Git-Tag: 0.34~15^2~3 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=0438a012ce75f5067aa95638519a30706494ab74;p=m6w6%2Flibmemcached Update protocol due to review comments: * Typedef the structs in the public interface * Removed the EVENT enum, and replaced it with a bitmask of it's own type * Added support for PAUSE events in the _binary_ protocol. ASCII is on the todo list :-) --- diff --git a/example/interface_v0.c b/example/interface_v0.c index 905b6ff5..041fe31e 100644 --- a/example/interface_v0.c +++ b/example/interface_v0.c @@ -519,7 +519,7 @@ static protocol_binary_response_status stat_command_handler(const void *cookie, return response_handler(cookie, header, (void*)&response); } -struct memcached_binary_protocol_callback_st interface_v0_impl= { +memcached_binary_protocol_callback_st interface_v0_impl= { .interface_version= 0, .interface.v0.comcode[PROTOCOL_BINARY_CMD_GET]= get_command_handler, .interface.v0.comcode[PROTOCOL_BINARY_CMD_SET]= set_command_handler, diff --git a/example/interface_v1.c b/example/interface_v1.c index 4ebc43db..3de38542 100644 --- a/example/interface_v1.c +++ b/example/interface_v1.c @@ -392,7 +392,7 @@ static protocol_binary_response_status version_handler(const void *cookie, return response_handler(cookie, version, (uint32_t)strlen(version)); } -struct memcached_binary_protocol_callback_st interface_v1_impl= { +memcached_binary_protocol_callback_st interface_v1_impl= { .interface_version= 1, .interface.v1= { .add= add_handler, diff --git a/example/memcached_light.c b/example/memcached_light.c index cac0cf9a..741ef82e 100644 --- a/example/memcached_light.c +++ b/example/memcached_light.c @@ -41,8 +41,8 @@ #include #include "storage.h" -extern struct memcached_binary_protocol_callback_st interface_v0_impl; -extern struct memcached_binary_protocol_callback_st interface_v1_impl; +extern memcached_binary_protocol_callback_st interface_v0_impl; +extern memcached_binary_protocol_callback_st interface_v1_impl; static int server_sockets[1024]; static int num_server_sockets= 0; @@ -227,7 +227,7 @@ int main(int argc, char **argv) { bool port_specified= false; int cmd; - struct memcached_binary_protocol_callback_st *interface= &interface_v0_impl; + memcached_binary_protocol_callback_st *interface= &interface_v0_impl; while ((cmd= getopt(argc, argv, "v1p:?")) != EOF) { @@ -364,17 +364,16 @@ static void work(void) assert(c != NULL); fds[max_poll].events= 0; - switch (memcached_protocol_client_work(c)) - { - case WRITE_EVENT: - case READ_WRITE_EVENT: + memcached_protocol_event_t events= memcached_protocol_client_work(c); + if (events & MEMCACHED_PROTOCOL_WRITE_EVENT) fds[max_poll].events= POLLOUT; - /* FALLTHROUGH */ - case READ_EVENT: - fds[max_poll].events |= POLLIN; - break; - case ERROR_EVENT: - default: /* ERROR or unknown state.. close */ + + if (events & MEMCACHED_PROTOCOL_READ_EVENT) + fds[max_poll].events= POLLIN; + + if (!(events & MEMCACHED_PROTOCOL_PAUSE_EVENT || + fds[max_poll].events != 0)) + { memcached_protocol_client_destroy(c); close(fds[x].fd); fds[x].events= 0; diff --git a/libmemcached/memcached/protocol_binary.h b/libmemcached/memcached/protocol_binary.h index c8888308..b2809406 100644 --- a/libmemcached/memcached/protocol_binary.h +++ b/libmemcached/memcached/protocol_binary.h @@ -71,7 +71,9 @@ extern "C" PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL = 0x06, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND = 0x81, PROTOCOL_BINARY_RESPONSE_ENOMEM = 0x82, - PROTOCOL_BINARY_RESPONSE_EIO = 0xff + + PROTOCOL_BINARY_RESPONSE_PAUSE = 0xfe00, + PROTOCOL_BINARY_RESPONSE_EIO = 0xff00 } protocol_binary_response_status; /** diff --git a/libmemcached/protocol/ascii_handler.c b/libmemcached/protocol/ascii_handler.c index 8238a36d..19aff115 100644 --- a/libmemcached/protocol/ascii_handler.c +++ b/libmemcached/protocol/ascii_handler.c @@ -16,7 +16,7 @@ static uint16_t parse_ascii_key(char **start) { uint16_t len= 0; - char *c = *start; + char *c= *start; /* Strip leading whitespaces */ while (isspace(*c)) { @@ -47,7 +47,7 @@ static uint16_t parse_ascii_key(char **start) * @return status of the spool operation */ static protocol_binary_response_status -spool_string(struct memcached_protocol_client_st *client, const char *text) +spool_string(memcached_protocol_client_st *client, const char *text) { return client->root->spool(client, text, strlen(text)); } @@ -57,7 +57,7 @@ spool_string(struct memcached_protocol_client_st *client, const char *text) * format of the command being sent * @param client the client to send the message to */ -static void send_command_usage(struct memcached_protocol_client_st *client) +static void send_command_usage(memcached_protocol_client_st *client) { const char *errmsg[]= { [GET_CMD]= "CLIENT_ERROR: Syntax error: get *\r\n", @@ -94,7 +94,7 @@ ascii_version_response_handler(const void *cookie, const void *text, uint32_t textlen) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; spool_string(client, "VERSION "); client->root->spool(client, text, textlen); spool_string(client, "\r\n"); @@ -120,17 +120,17 @@ ascii_get_response_handler(const void *cookie, uint32_t flags, uint64_t cas) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; char buffer[300]; strcpy(buffer, "VALUE "); - const char *source = key; - char *dest = buffer + 6; + const char *source= key; + char *dest= buffer + 6; for (int x= 0; x < keylen; ++x) { if (*source != '\0' && !isspace(*source) && !iscntrl(*source)) { - *dest = *source; + *dest= *source; } else { @@ -176,7 +176,7 @@ ascii_stat_response_handler(const void *cookie, uint32_t bodylen) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (key != NULL) { @@ -200,7 +200,7 @@ ascii_stat_response_handler(const void *cookie, * @param buffer the complete get(s) command * @param end the last character in the command */ -static void ascii_process_gets(struct memcached_protocol_client_st *client, +static void ascii_process_gets(memcached_protocol_client_st *client, char *buffer, char *end) { char *key= buffer; @@ -265,7 +265,7 @@ static int ascii_tokenize_command(char *str, char *end, char **vec, int size) } /* zero-terminate it for easier parsing later on */ - *str = '\0'; + *str= '\0'; ++str; /* Is the vector full? */ @@ -292,7 +292,7 @@ static void recover_tokenize_command(char *start, char *end) while (start < end) { if (*start == '\0') - *start = ' '; + *start= ' '; ++start; } @@ -308,7 +308,7 @@ static enum ascii_cmd ascii_to_cmd(char *start, size_t length) const char *cmd; size_t len; enum ascii_cmd cc; - } commands[] = { + } commands[]= { { .cmd= "get", .len= 3, .cc= GET_CMD }, { .cmd= "gets", .len= 4, .cc= GETS_CMD }, { .cmd= "set", .len= 3, .cc= SET_CMD }, @@ -353,7 +353,7 @@ static enum ascii_cmd ascii_to_cmd(char *start, size_t length) * @param tokens the command as a vector * @param ntokens the number of items in the vector */ -static void process_delete(struct memcached_protocol_client_st *client, +static void process_delete(memcached_protocol_client_st *client, char **tokens, int ntokens) { char *key= tokens[1]; @@ -390,7 +390,7 @@ static void process_delete(struct memcached_protocol_client_st *client, } } -static void process_arithmetic(struct memcached_protocol_client_st *client, +static void process_arithmetic(memcached_protocol_client_st *client, char **tokens, int ntokens) { char *key= tokens[1]; @@ -404,7 +404,7 @@ static void process_arithmetic(struct memcached_protocol_client_st *client, uint64_t cas; uint64_t result; - uint64_t delta = strtoull(tokens[2], NULL, 10); + uint64_t delta= strtoull(tokens[2], NULL, 10); protocol_binary_response_status rval; if (client->ascii_command == INCR_CMD) @@ -454,7 +454,7 @@ static void process_arithmetic(struct memcached_protocol_client_st *client, * @param key pointer to the first character after "stats" * @param end pointer to the "\n" */ -static void process_stats(struct memcached_protocol_client_st *client, +static void process_stats(memcached_protocol_client_st *client, char *key, char *end) { if (client->root->callback->interface.v1.stat == NULL) @@ -471,7 +471,7 @@ static void process_stats(struct memcached_protocol_client_st *client, ascii_stat_response_handler); } -static void process_version(struct memcached_protocol_client_st *client, +static void process_version(memcached_protocol_client_st *client, char **tokens, int ntokens) { (void)tokens; @@ -491,7 +491,7 @@ static void process_version(struct memcached_protocol_client_st *client, ascii_version_response_handler); } -static void process_flush(struct memcached_protocol_client_st *client, +static void process_flush(memcached_protocol_client_st *client, char **tokens, int ntokens) { if (ntokens > 2) @@ -509,7 +509,7 @@ static void process_flush(struct memcached_protocol_client_st *client, uint32_t timeout= 0; if (ntokens == 2) { - timeout = (uint32_t)strtoul(tokens[1], NULL, 10); + timeout= (uint32_t)strtoul(tokens[1], NULL, 10); } protocol_binary_response_status rval; @@ -534,7 +534,7 @@ static void process_flush(struct memcached_protocol_client_st *client, * 0 storage command completed, continue processing * 1 We need more data, so just go ahead and wait for more! */ -static inline int process_storage_command(struct memcached_protocol_client_st *client, +static inline int process_storage_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -548,12 +548,12 @@ static inline int process_storage_command(struct memcached_protocol_client_st *c return -1; } - uint32_t flags = (uint32_t)strtoul(tokens[2], NULL, 10); - uint32_t timeout = (uint32_t)strtoul(tokens[3], NULL, 10); - unsigned long nbytes = strtoul(tokens[4], NULL, 10); + uint32_t flags= (uint32_t)strtoul(tokens[2], NULL, 10); + uint32_t timeout= (uint32_t)strtoul(tokens[3], NULL, 10); + unsigned long nbytes= strtoul(tokens[4], NULL, 10); /* Do we have all data? */ - unsigned long need = nbytes + (unsigned long)((*end - start) + 1) + 2; /* \n\r\n */ + unsigned long need= nbytes + (unsigned long)((*end - start) + 1) + 2; /* \n\r\n */ if ((ssize_t)need > length) { /* Keep on reading */ @@ -561,7 +561,7 @@ static inline int process_storage_command(struct memcached_protocol_client_st *c return 1; } - void *data = (*end) + 1; + void *data= (*end) + 1; uint64_t cas= 0; uint64_t result_cas; protocol_binary_response_status rval; @@ -585,7 +585,7 @@ static inline int process_storage_command(struct memcached_protocol_client_st *c timeout, &result_cas); break; case CAS_CMD: - cas = strtoull(tokens[5], NULL, 10); + cas= strtoull(tokens[5], NULL, 10); /* FALLTHROUGH */ case REPLACE_CMD: rval= client->root->callback->interface.v1.replace(client, key, @@ -661,7 +661,7 @@ static inline int process_storage_command(struct memcached_protocol_client_st *c return 0; } -static int process_cas_command(struct memcached_protocol_client_st *client, +static int process_cas_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -680,7 +680,7 @@ static int process_cas_command(struct memcached_protocol_client_st *client, return process_storage_command(client, tokens, ntokens, start, end, length); } -static int process_set_command(struct memcached_protocol_client_st *client, +static int process_set_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -699,7 +699,7 @@ static int process_set_command(struct memcached_protocol_client_st *client, return process_storage_command(client, tokens, ntokens, start, end, length); } -static int process_add_command(struct memcached_protocol_client_st *client, +static int process_add_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -718,7 +718,7 @@ static int process_add_command(struct memcached_protocol_client_st *client, return process_storage_command(client, tokens, ntokens, start, end, length); } -static int process_replace_command(struct memcached_protocol_client_st *client, +static int process_replace_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -737,7 +737,7 @@ static int process_replace_command(struct memcached_protocol_client_st *client, return process_storage_command(client, tokens, ntokens, start, end, length); } -static int process_append_command(struct memcached_protocol_client_st *client, +static int process_append_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -756,7 +756,7 @@ static int process_append_command(struct memcached_protocol_client_st *client, return process_storage_command(client, tokens, ntokens, start, end, length); } -static int process_prepend_command(struct memcached_protocol_client_st *client, +static int process_prepend_command(memcached_protocol_client_st *client, char **tokens, int ntokens, char *start, char **end, ssize_t length) { @@ -780,7 +780,7 @@ static int process_prepend_command(struct memcached_protocol_client_st *client, * a optimal ascii support, I just convert the ASCII commands to the binary * protocol and calls back into the command handlers for the binary protocol ;) */ -enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr) +memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr) { char *ptr= (char*)client->root->input_buffer; *endptr= ptr; @@ -791,7 +791,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memca if (end == NULL) { *endptr= ptr; - return READ_EVENT; + return MEMCACHED_PROTOCOL_READ_EVENT; } client->ascii_command= ascii_to_cmd(ptr, (size_t)(*length)); @@ -869,7 +869,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memca if (client->root->callback->interface.v1.quit != NULL) client->root->callback->interface.v1.quit(client); - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } break; @@ -892,9 +892,9 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memca } if (error == -1) - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; else if (error == 1) - return READ_EVENT; + return MEMCACHED_PROTOCOL_READ_EVENT; } /* Move past \n */ @@ -903,6 +903,6 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memca ptr= end; } while (*length > 0); - *endptr = ptr; - return READ_EVENT; + *endptr= ptr; + return MEMCACHED_PROTOCOL_READ_EVENT; } diff --git a/libmemcached/protocol/ascii_handler.h b/libmemcached/protocol/ascii_handler.h index e8737921..02a1a82d 100644 --- a/libmemcached/protocol/ascii_handler.h +++ b/libmemcached/protocol/ascii_handler.h @@ -3,6 +3,6 @@ #define LIBMEMCACHED_PROTOCOL_ASCII_HANDLER_H LIBMEMCACHED_LOCAL -enum MEMCACHED_PROTOCOL_EVENT memcached_ascii_protocol_process_data(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr); +memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr); #endif diff --git a/libmemcached/protocol/binary_handler.c b/libmemcached/protocol/binary_handler.c index 23aeb5f9..27581ec8 100644 --- a/libmemcached/protocol/binary_handler.c +++ b/libmemcached/protocol/binary_handler.c @@ -30,7 +30,7 @@ raw_response_handler(const void *cookie, protocol_binary_request_header *request, protocol_binary_response_header *response) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->pedantic && !memcached_binary_protocol_pedantic_check_response(request, response)) @@ -106,7 +106,7 @@ get_response_handler(const void *cookie, uint32_t flags, uint64_t cas) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; uint8_t opcode= client->current_command->request.opcode; if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETQ) @@ -129,7 +129,7 @@ get_response_handler(const void *cookie, }; protocol_binary_response_status rval; - const protocol_binary_response_status success = PROTOCOL_BINARY_RESPONSE_SUCCESS; + const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS; if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success || (rval= client->root->spool(client, key, keylen)) != success || (rval= client->root->spool(client, body, bodylen)) != success) @@ -155,7 +155,7 @@ stat_response_handler(const void *cookie, const void *body, uint32_t bodylen) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; protocol_binary_response_no_extras response= { .message.header.response= { @@ -169,7 +169,7 @@ stat_response_handler(const void *cookie, }; protocol_binary_response_status rval; - const protocol_binary_response_status success = PROTOCOL_BINARY_RESPONSE_SUCCESS; + const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS; if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success || (rval= client->root->spool(client, key, keylen)) != success || (rval= client->root->spool(client, body, bodylen)) != success) @@ -191,7 +191,7 @@ version_response_handler(const void *cookie, const void *text, uint32_t textlen) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; protocol_binary_response_no_extras response= { .message.header.response= { @@ -204,7 +204,7 @@ version_response_handler(const void *cookie, }; protocol_binary_response_status rval; - const protocol_binary_response_status success = PROTOCOL_BINARY_RESPONSE_SUCCESS; + const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS; if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success || (rval= client->root->spool(client, text, textlen)) != success) { @@ -228,7 +228,7 @@ add_command_handler(const void *cookie, { protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.add != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -285,7 +285,7 @@ decrement_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.decrement != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -314,7 +314,7 @@ decrement_command_handler(const void *cookie, .cas= ntohll(cas), .bodylen= htonl(8) }, - .body.value = htonll(result) + .body.value= htonll(result) } }; rval= response_handler(cookie, header, (void*)&response); @@ -343,7 +343,7 @@ delete_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.delete != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -390,7 +390,7 @@ flush_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.flush != NULL) { protocol_binary_request_flush *flush= (void*)header; @@ -441,7 +441,7 @@ get_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.get != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -480,7 +480,7 @@ increment_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.increment != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -509,7 +509,7 @@ increment_command_handler(const void *cookie, .cas= ntohll(cas), .bodylen= htonl(8) }, - .body.value = htonll(result) + .body.value= htonll(result) } }; @@ -538,16 +538,16 @@ noop_command_handler(const void *cookie, protocol_binary_request_header *header, memcached_binary_protocol_raw_response_handler response_handler) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.noop != NULL) { client->root->callback->interface.v1.noop(cookie); } protocol_binary_response_no_extras response= { - .message = { - .header.response = { - .magic = PROTOCOL_BINARY_RES, + .message= { + .header.response= { + .magic= PROTOCOL_BINARY_RES, .opcode= PROTOCOL_BINARY_CMD_NOOP, .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS), .opaque= header->request.opaque, @@ -573,7 +573,7 @@ append_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.append != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -627,7 +627,7 @@ prepend_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.prepend != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -677,15 +677,15 @@ quit_command_handler(const void *cookie, protocol_binary_request_header *header, memcached_binary_protocol_raw_response_handler response_handler) { - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.quit != NULL) { client->root->callback->interface.v1.quit(cookie); } protocol_binary_response_no_extras response= { - .message = { - .header.response = { + .message= { + .header.response= { .magic= PROTOCOL_BINARY_RES, .opcode= PROTOCOL_BINARY_CMD_QUIT, .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS), @@ -718,7 +718,7 @@ replace_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.replace != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -776,7 +776,7 @@ set_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.set != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -834,7 +834,7 @@ stat_command_handler(const void *cookie, (void)response_handler; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.stat != NULL) { uint16_t keylen= ntohs(header->request.keylen); @@ -868,7 +868,7 @@ version_command_handler(const void *cookie, (void)header; protocol_binary_response_status rval; - struct memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (void*)cookie; if (client->root->callback->interface.v1.version != NULL) { rval= client->root->callback->interface.v1.version(cookie, @@ -924,7 +924,7 @@ static memcached_binary_protocol_command_handler comcode_v0_v1_remap[256]= { * @return true if success or false if a fatal error occured so that the * connection should be shut down. */ -static bool execute_command(struct memcached_protocol_client_st *client, protocol_binary_request_header *header) +static protocol_binary_response_status execute_command(memcached_protocol_client_st *client, protocol_binary_request_header *header) { if (client->root->pedantic && memcached_binary_protocol_pedantic_check_request(header)) @@ -970,7 +970,8 @@ static bool execute_command(struct memcached_protocol_client_st *client, protoco } if (rval != PROTOCOL_BINARY_RESPONSE_SUCCESS && - rval != PROTOCOL_BINARY_RESPONSE_EIO) + rval != PROTOCOL_BINARY_RESPONSE_EIO && + rval != PROTOCOL_BINARY_RESPONSE_PAUSE) { protocol_binary_response_no_extras response= { .message= { @@ -990,7 +991,7 @@ static bool execute_command(struct memcached_protocol_client_st *client, protoco client->root->callback->post_execute(client, header); } - return rval != PROTOCOL_BINARY_RESPONSE_EIO; + return rval; } /* @@ -998,7 +999,7 @@ static bool execute_command(struct memcached_protocol_client_st *client, protoco ** "PROTOECTED" INTERFACE ** ********************************************************************** */ -enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr) +memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr) { /* try to parse all of the received packets */ protocol_binary_request_header *header; @@ -1006,7 +1007,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memc if (header->request.magic != (uint8_t)PROTOCOL_BINARY_REQ) { client->error= EINVAL; - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } ssize_t len= *length; @@ -1014,13 +1015,16 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memc (len >= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen)))) { /* I have the complete package */ - client->current_command = header; - if (!execute_command(client, header)) + client->current_command= header; + protocol_binary_response_status rv= execute_command(client, header); + + if (rv == PROTOCOL_BINARY_RESPONSE_EIO) { *length= len; *endptr= (void*)header; - return ERROR_EVENT; - } + return MEMCACHED_PROTOCOL_ERROR_EVENT; + } else if (rv == PROTOCOL_BINARY_RESPONSE_PAUSE) + return MEMCACHED_PROTOCOL_PAUSE_EVENT; ssize_t total= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen)); len -= total; @@ -1039,12 +1043,11 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memc header= (void*)client->root->input_buffer; } } + *length= len; + *endptr= (void*)header; } - *length= len; - *endptr= (void*)header; - - return READ_EVENT; + return MEMCACHED_PROTOCOL_READ_EVENT; } /* @@ -1052,12 +1055,12 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memc ** PUBLIC INTERFACE ** ********************************************************************** */ -struct memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(struct memcached_protocol_st *instance) +memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance) { return instance->callback; } -void memcached_binary_protocol_set_callbacks(struct memcached_protocol_st *instance, struct memcached_binary_protocol_callback_st *callback) +void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback) { instance->callback= callback; } @@ -1068,12 +1071,12 @@ memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw return raw_response_handler; } -void memcached_binary_protocol_set_pedantic(struct memcached_protocol_st *instance, bool enable) +void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable) { instance->pedantic= enable; } -bool memcached_binary_protocol_get_pedantic(struct memcached_protocol_st *instance) +bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance) { return instance->pedantic; } diff --git a/libmemcached/protocol/binary_handler.h b/libmemcached/protocol/binary_handler.h index 7b1d0aca..a21165b2 100644 --- a/libmemcached/protocol/binary_handler.h +++ b/libmemcached/protocol/binary_handler.h @@ -3,13 +3,13 @@ #define LIBMEMCACHED_PROTOCOL_BINARY_HANDLER_H LIBMEMCACHED_LOCAL -bool memcached_binary_protocol_pedantic_check_request(protocol_binary_request_header *request); +bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request); LIBMEMCACHED_LOCAL -bool memcached_binary_protocol_pedantic_check_response(protocol_binary_request_header *request, - protocol_binary_response_header *response); +bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request, + const protocol_binary_response_header *response); LIBMEMCACHED_LOCAL -enum MEMCACHED_PROTOCOL_EVENT memcached_binary_protocol_process_data(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr); +memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr); #endif diff --git a/libmemcached/protocol/callback.h b/libmemcached/protocol/callback.h index c1f8c632..826a317d 100644 --- a/libmemcached/protocol/callback.h +++ b/libmemcached/protocol/callback.h @@ -20,7 +20,7 @@ * @param cas The CAS value to insert into the response (should be 0 * if you don't care) */ -typedef protocol_binary_response_status +typedef protocol_binary_response_status (*memcached_binary_protocol_get_response_handler)(const void *cookie, const void *key, uint16_t keylen, @@ -30,14 +30,14 @@ typedef protocol_binary_response_status uint64_t cas); /** * Callback to send data back from a STAT command - * + * * @param cookie Just pass along the cookie supplied in the callback * @param key What to insert as key in the reply * @param keylen The length of the key * @param body What to store in the body of the package * @param bodylen The number of bytes of the body */ -typedef protocol_binary_response_status +typedef protocol_binary_response_status (*memcached_binary_protocol_stat_response_handler)(const void *cookie, const void *key, uint16_t keylen, @@ -45,12 +45,12 @@ typedef protocol_binary_response_status uint32_t bodylen); /** * Callback to send data back from a VERSION command - * + * * @param cookie Just pass along the cookie supplied in the callback * @param text The version string * @param length The number of bytes in the version string */ -typedef protocol_binary_response_status +typedef protocol_binary_response_status (*memcached_binary_protocol_version_response_handler)(const void *cookie, const void *text, uint32_t length); @@ -58,7 +58,7 @@ typedef protocol_binary_response_status /** * In the low level interface you need to format the response - * packet yourself (giving you complete freedom :-) + * packet yourself (giving you complete freedom :-) * * @param cookie Just pass along the cookie supplied in the callback * @param request Pointer to the request packet you are sending a reply to @@ -72,7 +72,7 @@ typedef protocol_binary_response_status (*memcached_binary_protocol_raw_response /** * In the low lever interface you have to do most of the work by * yourself, but it also gives you a lot of freedom :-) - * @param cookie identification for this connection, just pass it along to + * @param cookie identification for this connection, just pass it along to * the response handler * @param header the command received over the wire. Never try to access * anything outside the command. @@ -84,22 +84,23 @@ typedef protocol_binary_response_status (*memcached_binary_protocol_command_hand /** * The raw interface to the packets is implemented in version 0. It contains - * just an array with command handlers. The inxed in the array is the + * just an array with command handlers. The inxed in the array is the * com code. */ -struct memcached_binary_protocol_callback_v0_st { +typedef struct { memcached_binary_protocol_command_handler comcode[256]; -}; +} memcached_binary_protocol_callback_v0_st; + /** * The first version of the callback struct containing all of the * documented commands in the initial release of the binary protocol * (aka. memcached 1.4.0). - * + * * You might miss the Q commands (addq etc) but the response function * knows how to deal with them so you don't need to worry about that :-) */ -struct memcached_binary_protocol_callback_v1_st { +typedef struct { /** * Add an item to the cache * @param cookie id of the client receiving the command @@ -111,13 +112,13 @@ struct memcached_binary_protocol_callback_v1_st { * @param exptime the expiry time for the key-value pair * @param cas the resulting cas for the add operation (if success) */ - protocol_binary_response_status (*add)(const void *cookie, - const void *key, + protocol_binary_response_status (*add)(const void *cookie, + const void *key, uint16_t keylen, - const void* val, - uint32_t vallen, - uint32_t flags, - uint32_t exptime, + const void* val, + uint32_t vallen, + uint32_t flags, + uint32_t exptime, uint64_t *cas); /** @@ -130,13 +131,13 @@ struct memcached_binary_protocol_callback_v1_st { * @param vallen the length of the data * @param cas the CAS in the request * @param result_cas the resulting cas for the append operation - * + * */ - protocol_binary_response_status (*append)(const void *cookie, - const void *key, - uint16_t keylen, - const void* val, - uint32_t vallen, + protocol_binary_response_status (*append)(const void *cookie, + const void *key, + uint16_t keylen, + const void* val, + uint32_t vallen, uint64_t cas, uint64_t *result_cas); @@ -152,13 +153,13 @@ struct memcached_binary_protocol_callback_v1_st { * @param cas the CAS in the request * @param result the result from the decrement * @param result_cas the cas of the item - * + * */ - protocol_binary_response_status (*decrement)(const void *cookie, - const void *key, - uint16_t keylen, - uint64_t delta, - uint64_t initial, + protocol_binary_response_status (*decrement)(const void *cookie, + const void *key, + uint16_t keylen, + uint64_t delta, + uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas); @@ -171,9 +172,9 @@ struct memcached_binary_protocol_callback_v1_st { * @param len the length of the key * @param cas the CAS in the request */ - protocol_binary_response_status (*delete)(const void *cookie, - const void *key, - uint16_t keylen, + protocol_binary_response_status (*delete)(const void *cookie, + const void *key, + uint16_t keylen, uint64_t cas); @@ -183,7 +184,7 @@ struct memcached_binary_protocol_callback_v1_st { * @param cookie id of the client receiving the command * @param when when the cache should be flushed (0 == immediately) */ - protocol_binary_response_status (*flush)(const void *cookie, + protocol_binary_response_status (*flush)(const void *cookie, uint32_t when); @@ -196,9 +197,9 @@ struct memcached_binary_protocol_callback_v1_st { * @param len the length of the key * @param response_handler to send the result back to the client */ - protocol_binary_response_status (*get)(const void *cookie, - const void *key, - uint16_t keylen, + protocol_binary_response_status (*get)(const void *cookie, + const void *key, + uint16_t keylen, memcached_binary_protocol_get_response_handler response_handler); /** @@ -213,21 +214,21 @@ struct memcached_binary_protocol_callback_v1_st { * @param cas the CAS in the request * @param result the result from the decrement * @param result_cas the cas of the item - * + * */ - protocol_binary_response_status (*increment)(const void *cookie, - const void *key, - uint16_t keylen, - uint64_t delta, - uint64_t initial, - uint32_t expiration, + protocol_binary_response_status (*increment)(const void *cookie, + const void *key, + uint16_t keylen, + uint64_t delta, + uint64_t initial, + uint32_t expiration, uint64_t *result, uint64_t *result_cas); /** * The noop command was received. This is just a notification callback (the * response is automatically created). - * + * * @param cookie id of the client receiving the command */ protocol_binary_response_status (*noop)(const void *cookie); @@ -242,20 +243,20 @@ struct memcached_binary_protocol_callback_v1_st { * @param vallen the length of the data * @param cas the CAS in the request * @param result-cas the cas id of the item - * + * */ - protocol_binary_response_status (*prepend)(const void *cookie, - const void *key, - uint16_t keylen, - const void* val, - uint32_t vallen, + protocol_binary_response_status (*prepend)(const void *cookie, + const void *key, + uint16_t keylen, + const void* val, + uint32_t vallen, uint64_t cas, uint64_t *result_cas); /** * The quit command was received. This is just a notification callback (the * response is automatically created). - * + * * @param cookie id of the client receiving the command */ protocol_binary_response_status (*quit)(const void *cookie); @@ -274,13 +275,13 @@ struct memcached_binary_protocol_callback_v1_st { * @param cas the cas id in the request * @param result_cas the cas id of the item */ - protocol_binary_response_status (*replace)(const void *cookie, - const void *key, + protocol_binary_response_status (*replace)(const void *cookie, + const void *key, uint16_t keylen, - const void* val, - uint32_t vallen, - uint32_t flags, - uint32_t exptime, + const void* val, + uint32_t vallen, + uint32_t flags, + uint32_t exptime, uint64_t cas, uint64_t *result_cas); @@ -298,13 +299,13 @@ struct memcached_binary_protocol_callback_v1_st { * @param cas the cas id in the request * @param result_cas the cas id of the new item */ - protocol_binary_response_status (*set)(const void *cookie, - const void *key, + protocol_binary_response_status (*set)(const void *cookie, + const void *key, uint16_t keylen, - const void* val, - uint32_t vallen, - uint32_t flags, - uint32_t exptime, + const void* val, + uint32_t vallen, + uint32_t flags, + uint32_t exptime, uint64_t cas, uint64_t *result_cas); @@ -318,11 +319,11 @@ struct memcached_binary_protocol_callback_v1_st { * @param keylen the length of the key * @param response_handler to send the result back to the client, but * don't send reply on success! - * + * */ - protocol_binary_response_status (*stat)(const void *cookie, - const void *key, - uint16_t keylen, + protocol_binary_response_status (*stat)(const void *cookie, + const void *key, + uint16_t keylen, memcached_binary_protocol_stat_response_handler response_handler); /** @@ -331,16 +332,16 @@ struct memcached_binary_protocol_callback_v1_st { * @param cookie id of the client receiving the command * @param response_handler to send the result back to the client, but * don't send reply on success! - * + * */ - protocol_binary_response_status (*version)(const void *cookie, + protocol_binary_response_status (*version)(const void *cookie, memcached_binary_protocol_version_response_handler response_handler); -}; +} memcached_binary_protocol_callback_v1_st; /** - * + * */ -struct memcached_binary_protocol_callback_st { +typedef struct { /** * The interface version used (set to 0 if you don't have any specialized * command handlers). @@ -355,7 +356,7 @@ struct memcached_binary_protocol_callback_st { * at the content you must ensure that you don't * try to access beyond the end of the message. */ - void (*pre_execute)(const void *cookie, + void (*pre_execute)(const void *cookie, protocol_binary_request_header *header); /** * Callback fired just after the command was exected (please note @@ -390,15 +391,15 @@ struct memcached_binary_protocol_callback_st { * passed as the pointer is valid as long as you use the protocol handler. */ union { - struct memcached_binary_protocol_callback_v0_st v0; + memcached_binary_protocol_callback_v0_st v0; /** * The first version of the callback struct containing all of the * documented commands in the initial release of the binary protocol * (aka. memcached 1.4.0). */ - struct memcached_binary_protocol_callback_v1_st v1; + memcached_binary_protocol_callback_v1_st v1; } interface; -}; +} memcached_binary_protocol_callback_st; #endif diff --git a/libmemcached/protocol/common.h b/libmemcached/protocol/common.h index 20fa16e5..48782a0c 100644 --- a/libmemcached/protocol/common.h +++ b/libmemcached/protocol/common.h @@ -23,8 +23,8 @@ * but some people still do). If it ever shows up as a performance thing * I'll look into optimizing this ;-) */ -typedef bool (*drain_func)(struct memcached_protocol_client_st *client); -typedef protocol_binary_response_status (*spool_func)(struct memcached_protocol_client_st *client, +typedef bool (*drain_func)(memcached_protocol_client_st *client); +typedef protocol_binary_response_status (*spool_func)(memcached_protocol_client_st *client, const void *data, size_t length); @@ -32,7 +32,7 @@ typedef protocol_binary_response_status (*spool_func)(struct memcached_protocol_ * Definition of the per instance structure. */ struct memcached_protocol_st { - struct memcached_binary_protocol_callback_st *callback; + memcached_binary_protocol_callback_st *callback; memcached_protocol_recv_func recv; memcached_protocol_send_func send; @@ -73,7 +73,7 @@ struct chunk_st { #define CHUNK_BUFFERSIZE 2048 -typedef enum MEMCACHED_PROTOCOL_EVENT (*process_data)(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr); +typedef memcached_protocol_event_t (*process_data)(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr); enum ascii_cmd { GET_CMD, @@ -96,7 +96,7 @@ enum ascii_cmd { }; struct memcached_protocol_client_st { - struct memcached_protocol_st *root; + memcached_protocol_st *root; int sock; int error; diff --git a/libmemcached/protocol/pedantic.c b/libmemcached/protocol/pedantic.c index d6304396..5d750c0a 100644 --- a/libmemcached/protocol/pedantic.c +++ b/libmemcached/protocol/pedantic.c @@ -7,7 +7,7 @@ #define ensure(a) if (!(a)) { return false; } -bool memcached_binary_protocol_pedantic_check_request(protocol_binary_request_header *request) +bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request) { ensure(request->request.magic == PROTOCOL_BINARY_REQ); ensure(request->request.datatype == PROTOCOL_BINARY_RAW_BYTES); @@ -99,8 +99,8 @@ bool memcached_binary_protocol_pedantic_check_request(protocol_binary_request_he return true; } -bool memcached_binary_protocol_pedantic_check_response(protocol_binary_request_header *request, - protocol_binary_response_header *response) +bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request, + const protocol_binary_response_header *response) { ensure(response->response.magic == PROTOCOL_BINARY_RES); ensure(response->response.datatype == PROTOCOL_BINARY_RAW_BYTES); diff --git a/libmemcached/protocol/protocol_handler.c b/libmemcached/protocol/protocol_handler.c index adba9ad7..fb90001d 100644 --- a/libmemcached/protocol/protocol_handler.c +++ b/libmemcached/protocol/protocol_handler.c @@ -124,13 +124,13 @@ static struct chunk_st *allocate_output_chunk(struct memcached_protocol_client_s return NULL; } - ret->offset = ret->nbytes = 0; - ret->next = NULL; - ret->size = CHUNK_BUFFERSIZE; + ret->offset= ret->nbytes= 0; + ret->next= NULL; + ret->size= CHUNK_BUFFERSIZE; ret->data= (void*)(ret + 1); if (client->output == NULL) { - client->output = client->output_tail = ret; + client->output= client->output_tail= ret; } else { @@ -159,7 +159,7 @@ static protocol_binary_response_status spool_output(struct memcached_protocol_cl return PROTOCOL_BINARY_RESPONSE_SUCCESS; } - size_t offset = 0; + size_t offset= 0; struct chunk_st *chunk= client->output; while (offset < length) @@ -172,10 +172,10 @@ static protocol_binary_response_status spool_output(struct memcached_protocol_cl } } - size_t bulk = length - offset; + size_t bulk= length - offset; if (bulk > chunk->size - chunk->nbytes) { - bulk = chunk->size - chunk->nbytes; + bulk= chunk->size - chunk->nbytes; } memcpy(chunk->data + chunk->nbytes, data, bulk); @@ -194,7 +194,7 @@ static protocol_binary_response_status spool_output(struct memcached_protocol_cl * so the implementors needs to provide an implementation of that interface * */ -static enum MEMCACHED_PROTOCOL_EVENT determine_protocol(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr) +static memcached_protocol_event_t determine_protocol(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr) { if (*client->root->input_buffer == (uint8_t)PROTOCOL_BINARY_REQ) { @@ -220,7 +220,7 @@ static enum MEMCACHED_PROTOCOL_EVENT determine_protocol(struct memcached_protoco const char *err= "CLIENT_ERROR: Unsupported protocol\r\n"; client->root->spool(client, err, strlen(err)); client->root->drain(client); - return ERROR_EVENT; /* Unsupported protocol */ + return MEMCACHED_PROTOCOL_ERROR_EVENT; /* Unsupported protocol */ } return client->work(client, length, endptr); @@ -250,10 +250,10 @@ struct memcached_protocol_st *memcached_protocol_create_instance(void) return NULL; } - ret->buffer_cache = cache_create("protocol_handler", + ret->buffer_cache= cache_create("protocol_handler", CHUNK_BUFFERSIZE + sizeof(struct chunk_st), 0, NULL, NULL); - if (ret->buffer_cache == NULL) + if (ret->buffer_cache == NULL) { free(ret->input_buffer); free(ret); @@ -288,7 +288,7 @@ void memcached_protocol_client_destroy(struct memcached_protocol_client_st *clie free(client); } -enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_protocol_client_st *client) +memcached_protocol_event_t memcached_protocol_client_work(struct memcached_protocol_client_st *client) { /* Try to send data and read from the socket */ bool more_data= true; @@ -314,9 +314,10 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_pr } void *endptr; - if (client->work(client, &len, &endptr) == ERROR_EVENT) + memcached_protocol_event_t events= client->work(client, &len, &endptr); + if (events == MEMCACHED_PROTOCOL_ERROR_EVENT) { - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } if (len > 0) @@ -327,7 +328,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_pr if (client->input_buffer == NULL) { client->error= ENOMEM; - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } memcpy(client->input_buffer, endptr, (size_t)len); client->input_buffer_offset= (size_t)len; @@ -338,7 +339,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_pr { /* Connection closed */ drain_output(client); - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } else { @@ -346,16 +347,20 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_pr { client->error= errno; /* mark this client as terminated! */ - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } - more_data = false; + more_data= false; } } while (more_data); if (!drain_output(client)) { - return ERROR_EVENT; + return MEMCACHED_PROTOCOL_ERROR_EVENT; } - return (client->output) ? READ_WRITE_EVENT : READ_EVENT; + memcached_protocol_event_t ret= MEMCACHED_PROTOCOL_READ_EVENT; + if (client->output) + ret|= MEMCACHED_PROTOCOL_READ_EVENT; + + return ret; } diff --git a/libmemcached/protocol_handler.h b/libmemcached/protocol_handler.h index ef816a0d..fe92a2cc 100644 --- a/libmemcached/protocol_handler.h +++ b/libmemcached/protocol_handler.h @@ -21,8 +21,8 @@ * and never assume anything about the internal layout / sizes of the * structures. */ -struct memcached_protocol_st; -struct memcached_protocol_client_st; +typedef struct memcached_protocol_st memcached_protocol_st; +typedef struct memcached_protocol_client_st memcached_protocol_client_st; /** * Function the protocol handler should call to receive data. @@ -37,7 +37,7 @@ struct memcached_protocol_client_st; */ typedef ssize_t (*memcached_protocol_recv_func)(const void *cookie, int fd, - void *buf, + void *buf, size_t nbuf); /** @@ -53,7 +53,7 @@ typedef ssize_t (*memcached_protocol_recv_func)(const void *cookie, */ typedef ssize_t (*memcached_protocol_send_func)(const void *cookie, int fd, - const void *buf, + const void *buf, size_t nbuf); /** @@ -62,14 +62,14 @@ typedef ssize_t (*memcached_protocol_send_func)(const void *cookie, * @return NULL if allocation of an instance fails */ LIBMEMCACHED_API -struct memcached_protocol_st *memcached_protocol_create_instance(void); +memcached_protocol_st *memcached_protocol_create_instance(void); /** * Get the callbacks associated with a protocol handler instance * @return the callbacks currently used */ LIBMEMCACHED_API -struct memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(struct memcached_protocol_st *instance); +memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance); /** * Set the callbacks to be used by the given protocol handler instance @@ -77,7 +77,7 @@ struct memcached_binary_protocol_callback_st *memcached_binary_protocol_get_call * @param callback the callbacks to use */ LIBMEMCACHED_API -void memcached_binary_protocol_set_callbacks(struct memcached_protocol_st *instance, struct memcached_binary_protocol_callback_st *callback); +void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback); /** * Should the library inspect the packages being sent and received and verify @@ -88,7 +88,7 @@ void memcached_binary_protocol_set_callbacks(struct memcached_protocol_st *insta * @param enable true if you want the library to check packages, false otherwise */ LIBMEMCACHED_API -void memcached_binary_protocol_set_pedantic(struct memcached_protocol_st *instance, bool enable); +void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable); /** * Is the library inpecting each package? @@ -96,7 +96,7 @@ void memcached_binary_protocol_set_pedantic(struct memcached_protocol_st *instan * @return true it the library is inspecting each package, false otherwise */ LIBMEMCACHED_API -bool memcached_binary_protocol_get_pedantic(struct memcached_protocol_st *instance); +bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance); /** * Destroy an instance of the protocol handler @@ -104,19 +104,19 @@ bool memcached_binary_protocol_get_pedantic(struct memcached_protocol_st *instan * @param instance The instance to destroy */ LIBMEMCACHED_API -void memcached_protocol_destroy_instance(struct memcached_protocol_st *instance); +void memcached_protocol_destroy_instance(memcached_protocol_st *instance); /** * Set the IO functions used by the instance to send and receive data. The - * functions should behave like recv(3socket) and send(3socket). - * + * functions should behave like recv(3socket) and send(3socket). + * * @param instance the instance to specify the IO functions for * @param recv the function to call for reciving data * @param send the function to call for sending data */ LIBMEMCACHED_API -void memached_protocol_set_io_functions(struct memcached_protocol_st *instance, - memcached_protocol_recv_func recv, +void memached_protocol_set_io_functions(memcached_protocol_st *instance, + memcached_protocol_recv_func recv, memcached_protocol_send_func send); @@ -124,45 +124,54 @@ void memached_protocol_set_io_functions(struct memcached_protocol_st *instance, * Create a new client instance and associate it with a socket * @param instance the protocol instance to bind the client to * @param sock the client socket - * @return NULL if allocation fails, otherwise an instance + * @return NULL if allocation fails, otherwise an instance */ LIBMEMCACHED_API -struct memcached_protocol_client_st *memcached_protocol_create_client(struct memcached_protocol_st *instance, int sock); +memcached_protocol_client_st *memcached_protocol_create_client(memcached_protocol_st *instance, int sock); /** * Destroy a client handle. - * The caller needs to close the socket accociated with the client + * The caller needs to close the socket accociated with the client * before calling this function. This function invalidates the * client memory area. * * @param client the client to destroy */ LIBMEMCACHED_API -void memcached_protocol_client_destroy(struct memcached_protocol_client_st *client); +void memcached_protocol_client_destroy(memcached_protocol_client_st *client); + +/** + * Error event means that the client encountered an error with the + * connection so you should shut it down + */ +#define MEMCACHED_PROTOCOL_ERROR_EVENT 1 +/** + * Please notify when there is more data available to read + */ +#define MEMCACHED_PROTOCOL_READ_EVENT 2 +/** + * Please notify when it is possible to send more data + */ +#define MEMCACHED_PROTOCOL_WRITE_EVENT 4 +/** + * Backed paused the execution for this client + */ +#define MEMCACHED_PROTOCOL_PAUSE_EVENT 8 /** - * The different events the client is interested in + * The different events the client is interested in. This is a bitmask of + * the constants defined above. */ -enum MEMCACHED_PROTOCOL_EVENT { - /* Error event means that the client encountered an error with the - * connection so you should shut it down */ - ERROR_EVENT, - /* Please notify when there is more data available to read */ - READ_EVENT, - /* Please notify when it is possible to send more data */ - WRITE_EVENT, - /* Please notify when it is possible to send or receive data */ - READ_WRITE_EVENT -}; +typedef uint32_t memcached_protocol_event_t; /** - * Let the client do some work. This might involve reading / sending data + * Let the client do some work. This might involve reading / sending data * to/from the client, or perform callbacks to execute a command. * @param client the client structure to work on * @return The next event the protocol handler will be notified for */ LIBMEMCACHED_API -enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_protocol_client_st *client); +memcached_protocol_event_t memcached_protocol_client_work(memcached_protocol_client_st *client); /** * Get the socket attached to a client handle @@ -170,7 +179,7 @@ enum MEMCACHED_PROTOCOL_EVENT memcached_protocol_client_work(struct memcached_pr * @return the socket handle */ LIBMEMCACHED_API -int memcached_protocol_client_get_socket(struct memcached_protocol_client_st *client); +int memcached_protocol_client_get_socket(memcached_protocol_client_st *client); /** * Get the error id socket attached to a client handle @@ -178,7 +187,7 @@ int memcached_protocol_client_get_socket(struct memcached_protocol_client_st *cl * @return the OS error code from the client */ LIBMEMCACHED_API -int memcached_protocol_client_get_errno(struct memcached_protocol_client_st *client); +int memcached_protocol_client_get_errno(memcached_protocol_client_st *client); /** * Get a raw response handler for the given cookie