X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=example%2Finterface_v0.c;h=ef5ba47b57324b384a8c60e792205a57f5599cca;hb=0b11235514c679e2545176348ce56c1e19ba4d30;hp=5971366d4ba16deecdd6a0d5d52fd8488fa5f835;hpb=9131482f7923cf9e90b5a715b38e70e3a229b052;p=m6w6%2Flibmemcached diff --git a/example/interface_v0.c b/example/interface_v0.c index 5971366d..ef5ba47b 100644 --- a/example/interface_v0.c +++ b/example/interface_v0.c @@ -4,11 +4,11 @@ * in the protocol library. You might want to have your copy of the protocol * specification next to your coffee ;-) */ + +#include "config.h" + #include #include -#include -#include -#include #include #include #include @@ -16,9 +16,10 @@ #include #include -#include -#include "common.h" -#include "storage.h" +#include +#include +#include "example/storage.h" +#include "example/memcached_light.h" static protocol_binary_response_status noop_command_handler(const void *cookie, protocol_binary_request_header *header, @@ -53,7 +54,7 @@ static protocol_binary_response_status quit_command_handler(const void *cookie, response_handler(cookie, header, (void*)&response); /* I need a better way to signal to close the connection */ - return PROTOCOL_BINARY_RESPONSE_EIO; + return PROTOCOL_BINARY_RESPONSE_EINTERNAL; } static protocol_binary_response_status get_command_handler(const void *cookie, @@ -79,7 +80,7 @@ static protocol_binary_response_status get_command_handler(const void *cookie, msg.response.message.body.flags= htonl(item->flags); char *ptr= (char*)(msg.response.bytes + sizeof(*header) + 4); uint32_t bodysize= 4; - msg.response.message.header.response.cas= htonll(item->cas); + msg.response.message.header.response.cas= example_htonll(item->cas); if (opcode == PROTOCOL_BINARY_CMD_GETK || opcode == PROTOCOL_BINARY_CMD_GETKQ) { memcpy(ptr, item->key, item->nkey); @@ -92,6 +93,7 @@ static protocol_binary_response_status get_command_handler(const void *cookie, msg.response.message.header.response.bodylen= htonl(bodysize); msg.response.message.header.response.extlen= 4; + release_item(item); return response_handler(cookie, header, (void*)&msg); } else if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETK) @@ -172,54 +174,60 @@ static protocol_binary_response_status arithmetic_command_handler(const void *co }; uint16_t keylen= ntohs(header->request.keylen); - uint64_t initial= ntohll(req->message.body.initial); - uint64_t delta= ntohll(req->message.body.delta); + uint64_t initial= example_ntohll(req->message.body.initial); + uint64_t delta= example_ntohll(req->message.body.delta); uint32_t expiration= ntohl(req->message.body.expiration); + uint32_t flags= 0; void *key= req->bytes + sizeof(req->bytes); protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; + uint64_t value= initial; + struct item *item= get_item(key, keylen); - if (item == NULL) - { - item= create_item(key, keylen, NULL, sizeof(initial), 0, expiration); - if (item == 0) - { - rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; - } - else - { - memcpy(item->data, &initial, sizeof(initial)); - put_item(item); - } - } - else + if (item != NULL) { if (header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT || header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENTQ) { - (*(uint64_t*)item->data) += delta; + value= (*(uint64_t*)item->data) + delta; } else { if (delta > *(uint64_t*)item->data) { - *(uint64_t*)item->data= 0; + value= 0; } else { - *(uint64_t*)item->data -= delta; + value= *(uint64_t*)item->data - delta; } } - update_cas(item); + expiration= (uint32_t)item->exp; + flags= item->flags; + + release_item(item); + delete_item(key, keylen); + } + + item= create_item(key, keylen, NULL, sizeof(value), flags, (time_t)expiration); + if (item == NULL) + { + rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; + } + else + { + memcpy(item->data, &value, sizeof(value)); + put_item(item); } response.message.header.response.status= htons(rval); if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { response.message.header.response.bodylen= ntohl(8); - response.message.body.value= ntohll((*(uint64_t*)item->data)); - response.message.header.response.cas= ntohll(item->cas); + response.message.body.value= example_ntohll((*(uint64_t*)item->data)); + response.message.header.response.cas= example_ntohll(item->cas); + release_item(item); if (header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENTQ || header->request.opcode == PROTOCOL_BINARY_CMD_DECREMENTQ) { @@ -244,6 +252,7 @@ static protocol_binary_response_status version_command_handler(const void *cooki .opcode= PROTOCOL_BINARY_CMD_VERSION, .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS), .opaque= header->request.opaque, + .cas= 0, .bodylen= htonl((uint32_t)strlen(versionstring)) } }; @@ -259,13 +268,14 @@ static protocol_binary_response_status concat_command_handler(const void *cookie { protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; uint16_t keylen= ntohs(header->request.keylen); - uint64_t cas= ntohll(header->request.cas); + uint64_t cas= example_ntohll(header->request.cas); void *key= header + 1; uint32_t vallen= ntohl(header->request.bodylen) - keylen; void *val= (char*)key + keylen; struct item *item= get_item(key, keylen); - struct item *nitem; + struct item *nitem= NULL; + if (item == NULL) { rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; @@ -277,6 +287,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie else if ((nitem= create_item(key, keylen, NULL, item->size + vallen, item->flags, item->exp)) == NULL) { + release_item(item); rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else @@ -292,8 +303,12 @@ static protocol_binary_response_status concat_command_handler(const void *cookie memcpy(nitem->data, val, vallen); memcpy(((char*)(nitem->data)) + vallen, item->data, item->size); } + release_item(item); delete_item(key, keylen); put_item(nitem); + cas= nitem->cas; + release_item(nitem); + if (header->request.opcode == PROTOCOL_BINARY_CMD_APPEND || header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND) { @@ -304,7 +319,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie .opcode= header->request.opcode, .status= htons(rval), .opaque= header->request.opaque, - .cas= htonll(nitem->cas), + .cas= example_htonll(cas), } } }; @@ -323,7 +338,7 @@ static protocol_binary_response_status set_command_handler(const void *cookie, size_t datalen= ntohl(header->request.bodylen) - keylen - 8; protocol_binary_request_replace *request= (void*)header; uint32_t flags= ntohl(request->message.body.flags); - time_t timeout= ntohl(request->message.body.expiration); + time_t timeout= (time_t)ntohl(request->message.body.expiration); char *key= ((char*)header) + sizeof(*header) + 8; char *data= key + keylen; @@ -342,16 +357,21 @@ static protocol_binary_response_status set_command_handler(const void *cookie, { /* validate cas */ struct item* item= get_item(key, keylen); - if (item != NULL && item->cas != ntohll(header->request.cas)) + if (item != NULL) { - response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); - return response_handler(cookie, header, (void*)&response); + if (item->cas != example_ntohll(header->request.cas)) + { + release_item(item); + response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); + return response_handler(cookie, header, (void*)&response); + } + release_item(item); } } delete_item(key, keylen); struct item* item= create_item(key, keylen, data, datalen, flags, timeout); - if (item == 0) + if (item == NULL) { response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM); } @@ -361,9 +381,12 @@ static protocol_binary_response_status set_command_handler(const void *cookie, /* SETQ shouldn't return a message */ if (header->request.opcode == PROTOCOL_BINARY_CMD_SET) { - response.message.header.response.cas= htonll(item->cas); + response.message.header.response.cas= example_htonll(item->cas); + release_item(item); return response_handler(cookie, header, (void*)&response); } + release_item(item); + return PROTOCOL_BINARY_RESPONSE_SUCCESS; } @@ -378,7 +401,7 @@ static protocol_binary_response_status add_command_handler(const void *cookie, size_t datalen= ntohl(header->request.bodylen) - keylen - 8; protocol_binary_request_add *request= (void*)header; uint32_t flags= ntohl(request->message.body.flags); - time_t timeout= ntohl(request->message.body.expiration); + time_t timeout= (time_t)ntohl(request->message.body.expiration); char *key= ((char*)header) + sizeof(*header) + 8; char *data= key + keylen; @@ -397,7 +420,7 @@ static protocol_binary_response_status add_command_handler(const void *cookie, if (item == NULL) { item= create_item(key, keylen, data, datalen, flags, timeout); - if (item == 0) + if (item == NULL) response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM); else { @@ -405,14 +428,17 @@ static protocol_binary_response_status add_command_handler(const void *cookie, /* ADDQ shouldn't return a message */ if (header->request.opcode == PROTOCOL_BINARY_CMD_ADD) { - response.message.header.response.cas= htonll(item->cas); + response.message.header.response.cas= example_htonll(item->cas); + release_item(item); return response_handler(cookie, header, (void*)&response); } + release_item(item); return PROTOCOL_BINARY_RESPONSE_SUCCESS; } } else { + release_item(item); response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); } @@ -427,7 +453,7 @@ static protocol_binary_response_status replace_command_handler(const void *cooki size_t datalen= ntohl(header->request.bodylen) - keylen - 8; protocol_binary_request_replace *request= (void*)header; uint32_t flags= ntohl(request->message.body.flags); - time_t timeout= ntohl(request->message.body.expiration); + time_t timeout= (time_t)ntohl(request->message.body.expiration); char *key= ((char*)header) + sizeof(*header) + 8; char *data= key + keylen; @@ -444,27 +470,38 @@ static protocol_binary_response_status replace_command_handler(const void *cooki struct item* item= get_item(key, keylen); if (item == NULL) + { response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); - else if (header->request.cas == 0 || ntohll(header->request.cas) == item->cas) + } + else if (header->request.cas == 0 || example_ntohll(header->request.cas) == item->cas) { + release_item(item); delete_item(key, keylen); item= create_item(key, keylen, data, datalen, flags, timeout); - if (item == 0) + + if (item == NULL) + { response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM); + } else { put_item(item); /* REPLACEQ shouldn't return a message */ if (header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE) { - response.message.header.response.cas= htonll(item->cas); + response.message.header.response.cas= example_htonll(item->cas); + release_item(item); return response_handler(cookie, header, (void*)&response); } + release_item(item); return PROTOCOL_BINARY_RESPONSE_SUCCESS; } } else + { response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); + release_item(item); + } return response_handler(cookie, header, (void*)&response); } @@ -488,8 +525,15 @@ 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= { - .interface_version= 0, +memcached_binary_protocol_callback_st interface_v0_impl= { + .interface_version= MEMCACHED_PROTOCOL_HANDLER_V0, +#ifdef FUTURE + /* + ** There is a number of bugs in the extra options for gcc causing + ** warning on these struct initializers. It hurts my heart to remove + ** it so I'll just leave it in here so that we can enable it when + ** we can drop support for the broken compilers + */ .interface.v0.comcode[PROTOCOL_BINARY_CMD_GET]= get_command_handler, .interface.v0.comcode[PROTOCOL_BINARY_CMD_SET]= set_command_handler, .interface.v0.comcode[PROTOCOL_BINARY_CMD_ADD]= add_command_handler, @@ -517,4 +561,36 @@ struct memcached_binary_protocol_callback_st interface_v0_impl= { .interface.v0.comcode[PROTOCOL_BINARY_CMD_FLUSHQ]= flush_command_handler, .interface.v0.comcode[PROTOCOL_BINARY_CMD_APPENDQ]= concat_command_handler, .interface.v0.comcode[PROTOCOL_BINARY_CMD_PREPENDQ]= concat_command_handler, +#endif }; + +void initialize_interface_v0_handler(void) +{ + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_GET]= get_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_SET]= set_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_ADD]= add_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_REPLACE]= replace_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_DELETE]= delete_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_INCREMENT]= arithmetic_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_DECREMENT]= arithmetic_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_QUIT]= quit_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_FLUSH]= flush_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_GETQ]= get_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_NOOP]= noop_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_VERSION]= version_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_GETK]= get_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_GETKQ]= get_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_APPEND]= concat_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_PREPEND]= concat_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_STAT]= stat_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_SETQ]= set_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_ADDQ]= add_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_REPLACEQ]= replace_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_DELETEQ]= delete_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_INCREMENTQ]= arithmetic_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_DECREMENTQ]= arithmetic_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_QUITQ]= quit_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_FLUSHQ]= flush_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_APPENDQ]= concat_command_handler; + interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_PREPENDQ]= concat_command_handler; +}