X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fresponse.c;h=c14dd1ff6688c6678922c5d4356c77e02bbe6e17;hb=c29c787187baac1f403668a5dbf8ba481b9a8c8e;hp=a87ac2491bad3690d4db473f7efdb1d0a41a3b09;hpb=7c7750f02368b570353ea109f23a0ea26d226e02;p=m6w6%2Flibmemcached diff --git a/libmemcached/response.c b/libmemcached/response.c index a87ac249..c14dd1ff 100644 --- a/libmemcached/response.c +++ b/libmemcached/response.c @@ -1,27 +1,34 @@ -/* - Memcached library - - memcached_response() is used to determine the return result - from an issued command. +/* LibMemcached + * Copyright (C) 2006-2009 Brian Aker + * All rights reserved. + * + * Use and distribution licensed under the BSD license. See + * the COPYING file in the parent directory for full text. + * + * Summary: memcached_response() is used to determine the return result from an issued command. + * */ #include "common.h" -static memcached_return_t textual_read_one_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result); -static memcached_return_t binary_read_one_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result); +static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result); +static memcached_return_t binary_read_one_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result); -memcached_return_t memcached_read_one_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result) +memcached_return_t memcached_read_one_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result) { memcached_server_response_decrement(ptr); if (result == NULL) - result = &ptr->root->result; + { + memcached_st *root= (memcached_st *)ptr->root; + result = &root->result; + } memcached_return_t rc; if (ptr->root->flags.binary_protocol) @@ -33,29 +40,31 @@ memcached_return_t memcached_read_one_response(memcached_server_st *ptr, rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE) - memcached_io_reset(ptr); + memcached_io_reset(ptr); return rc; } -memcached_return_t memcached_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result) +memcached_return_t memcached_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result) { /* We may have old commands in the buffer not set, first purge */ - if (ptr->root->flags.no_block) - (void)memcached_io_write(ptr, NULL, 0, 1); + if ((ptr->root->flags.no_block) && (memcached_is_processing_input(ptr->root) == false)) + { + (void)memcached_io_write(ptr, NULL, 0, true); + } /* * The previous implementation purged all pending requests and just * returned the last one. Purge all pending messages to ensure backwards * compatibility. - */ + */ if (ptr->root->flags.binary_protocol == false) while (memcached_server_response_count(ptr) > 1) { memcached_return_t rc= memcached_read_one_response(ptr, buffer, buffer_length, result); - + unlikely (rc != MEMCACHED_END && rc != MEMCACHED_STORED && rc != MEMCACHED_SUCCESS && @@ -64,15 +73,15 @@ memcached_return_t memcached_response(memcached_server_st *ptr, rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_NOTSTORED && rc != MEMCACHED_DATA_EXISTS) - return rc; + return rc; } return memcached_read_one_response(ptr, buffer, buffer_length, result); } -static memcached_return_t textual_value_fetch(memcached_server_st *ptr, - char *buffer, - memcached_result_st *result) +static memcached_return_t textual_value_fetch(memcached_server_write_instance_st ptr, + char *buffer, + memcached_result_st *result) { memcached_return_t rc= MEMCACHED_SUCCESS; char *string_ptr; @@ -81,6 +90,8 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, size_t value_length; size_t to_read; char *value_ptr; + ssize_t read_length= 0; + memcached_return_t rrc; if (ptr->root->flags.use_udp) return MEMCACHED_NOT_SUPPORTED; @@ -99,7 +110,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, char *key; size_t prefix_length; - key= result->key; + key= result->item_key; result->key_length= 0; for (prefix_length= ptr->root->prefix_key_length; !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++) @@ -113,7 +124,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, else prefix_length--; } - result->key[result->key_length]= 0; + result->item_key[result->key_length]= 0; } if (end_ptr == string_ptr) @@ -124,7 +135,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, if (end_ptr == string_ptr) goto read_error; for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - result->flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10); + result->item_flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10); if (end_ptr == string_ptr) goto read_error; @@ -150,7 +161,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, { string_ptr++; for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - result->cas= strtoull(next_ptr, &string_ptr, 10); + result->item_cas= strtoull(next_ptr, &string_ptr, 10); } if (end_ptr < string_ptr) @@ -164,7 +175,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, return MEMCACHED_MEMORY_ALLOCATION_FAILURE; } - value_ptr= memcached_string_value(&result->value); + value_ptr= memcached_string_value_mutable(&result->value); /* We read the \r\n into the string since not doing so is more cycles then the waster of memory to do so. @@ -173,8 +184,7 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, some people lazy about using the return length. */ to_read= (value_length) + 2; - ssize_t read_length= 0; - memcached_return_t rrc= memcached_io_read(ptr, value_ptr, to_read, &read_length); + rrc= memcached_io_read(ptr, value_ptr, to_read, &read_length); if (rrc != MEMCACHED_SUCCESS) return rrc; @@ -183,10 +193,10 @@ static memcached_return_t textual_value_fetch(memcached_server_st *ptr, goto read_error; } -/* This next bit blows the API, but this is internal....*/ + /* This next bit blows the API, but this is internal....*/ { char *char_ptr; - char_ptr= memcached_string_value(&result->value);; + char_ptr= memcached_string_value_mutable(&result->value);; char_ptr[value_length]= 0; char_ptr[value_length + 1]= 0; memcached_string_set_length(&result->value, value_length); @@ -200,9 +210,9 @@ read_error: return MEMCACHED_PARTIAL_READ; } -static memcached_return_t textual_read_one_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result) +static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result) { memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length); if (rc != MEMCACHED_SUCCESS) @@ -237,35 +247,35 @@ static memcached_return_t textual_read_one_response(memcached_server_st *ptr, return MEMCACHED_STAT; } else if (buffer[1] == 'E') /* SERVER_ERROR */ - { - char *rel_ptr; - char *startptr= buffer + 13, *endptr= startptr; - - while (*endptr != '\r' && *endptr != '\n') endptr++; - - /* - Yes, we could make this "efficent" but to do that we would need - to maintain more state for the size of the buffer. Why waste - memory in the struct, which is important, for something that - rarely should happen? - */ - rel_ptr= (char *)ptr->root->call_realloc(ptr->root, - ptr->cached_server_error, - (size_t) (endptr - startptr + 1)); - - if (rel_ptr == NULL) - { - /* If we happened to have some memory, we just null it since we don't know the size */ - if (ptr->cached_server_error) - ptr->cached_server_error[0]= 0; - return MEMCACHED_SERVER_ERROR; - } - ptr->cached_server_error= rel_ptr; - - memcpy(ptr->cached_server_error, startptr, (size_t) (endptr - startptr)); - ptr->cached_server_error[endptr - startptr]= 0; - return MEMCACHED_SERVER_ERROR; - } + { + char *rel_ptr; + char *startptr= buffer + 13, *endptr= startptr; + + while (*endptr != '\r' && *endptr != '\n') endptr++; + + /* + Yes, we could make this "efficent" but to do that we would need + to maintain more state for the size of the buffer. Why waste + memory in the struct, which is important, for something that + rarely should happen? + */ + rel_ptr= (char *)libmemcached_realloc(ptr->root, + ptr->cached_server_error, + (size_t) (endptr - startptr + 1)); + + if (rel_ptr == NULL) + { + /* If we happened to have some memory, we just null it since we don't know the size */ + if (ptr->cached_server_error) + ptr->cached_server_error[0]= 0; + return MEMCACHED_SERVER_ERROR; + } + ptr->cached_server_error= rel_ptr; + + memcpy(ptr->cached_server_error, startptr, (size_t) (endptr - startptr)); + ptr->cached_server_error[endptr - startptr]= 0; + return MEMCACHED_SERVER_ERROR; + } else if (buffer[1] == 'T') return MEMCACHED_STORED; else @@ -298,8 +308,8 @@ static memcached_return_t textual_read_one_response(memcached_server_st *ptr, return MEMCACHED_UNKNOWN_READ_FAILURE; } case 'I': /* CLIENT ERROR */ - /* We add back in one because we will need to search for END */ - memcached_server_response_increment(ptr); + /* We add back in one because we will need to search for END */ + memcached_server_response_increment(ptr); return MEMCACHED_ITEM; case 'C': /* CLIENT ERROR */ return MEMCACHED_CLIENT_ERROR; @@ -317,24 +327,12 @@ static memcached_return_t textual_read_one_response(memcached_server_st *ptr, /* NOTREACHED */ } -char *memcached_result_value(memcached_result_st *ptr) -{ - memcached_string_st *sptr= &ptr->value; - return memcached_string_value(sptr); -} - -size_t memcached_result_length(memcached_result_st *ptr) -{ - memcached_string_st *sptr= &ptr->value; - return memcached_string_length(sptr); -} - -static memcached_return_t binary_read_one_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result) +static memcached_return_t binary_read_one_response(memcached_server_write_instance_st ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result) { protocol_binary_response_header header; - + unlikely (memcached_safe_read(ptr, &header.bytes, sizeof(header.bytes)) != MEMCACHED_SUCCESS) return MEMCACHED_UNKNOWN_READ_FAILURE; @@ -343,8 +341,8 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, return MEMCACHED_PROTOCOL_ERROR; /* - ** Convert the header to host local endian! - */ + ** Convert the header to host local endian! + */ header.response.keylen= ntohs(header.response.keylen); header.response.status= ntohs(header.response.status); header.response.bodylen= ntohl(header.response.bodylen); @@ -366,17 +364,17 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, { uint16_t keylen= header.response.keylen; memcached_result_reset(result); - result->cas= header.response.cas; + result->item_cas= header.response.cas; - if (memcached_safe_read(ptr, &result->flags, - sizeof (result->flags)) != MEMCACHED_SUCCESS) + if (memcached_safe_read(ptr, &result->item_flags, + sizeof (result->item_flags)) != MEMCACHED_SUCCESS) return MEMCACHED_UNKNOWN_READ_FAILURE; - result->flags= ntohl(result->flags); + result->item_flags= ntohl(result->item_flags); bodylen -= header.response.extlen; result->key_length= keylen; - if (memcached_safe_read(ptr, result->key, keylen) != MEMCACHED_SUCCESS) + if (memcached_safe_read(ptr, result->item_key, keylen) != MEMCACHED_SUCCESS) return MEMCACHED_UNKNOWN_READ_FAILURE; bodylen -= keylen; @@ -384,7 +382,7 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, bodylen) != MEMCACHED_SUCCESS) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - char *vptr= memcached_string_value(&result->value); + char *vptr= memcached_string_value_mutable(&result->value); if (memcached_safe_read(ptr, vptr, bodylen) != MEMCACHED_SUCCESS) return MEMCACHED_UNKNOWN_READ_FAILURE; @@ -461,7 +459,7 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, } else if (header.response.bodylen) { - /* What should I do with the error message??? just discard it for now */ + /* What should I do with the error message??? just discard it for now */ char hole[SMALL_STRING_LEN]; while (bodylen > 0) { @@ -474,7 +472,7 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, /* This might be an error from one of the quiet commands.. if * so, just throw it away and get the next one. What about creating * a callback to the user with the error information? - */ + */ switch (header.response.opcode) { case PROTOCOL_BINARY_CMD_SETQ: @@ -514,6 +512,6 @@ static memcached_return_t binary_read_one_response(memcached_server_st *ptr, rc= MEMCACHED_PROTOCOL_ERROR; break; } - + return rc; }