From: Brian Aker Date: Sat, 13 Oct 2007 00:13:33 +0000 (-0700) Subject: Updates to clean server structure. X-Git-Tag: 0_7~43 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=7ef83f5c1f71a8527a5f3001d72772ac692bcf14;p=m6w6%2Flibmemcached Updates to clean server structure. Addition for wildcard tests. Fix for multi, aka three, hosts for key reads. --- diff --git a/include/memcached.h b/include/memcached.h index 558fbb09..6797279b 100644 --- a/include/memcached.h +++ b/include/memcached.h @@ -88,6 +88,7 @@ struct memcached_server_st { unsigned int port; int fd; unsigned int stack_responses; + unsigned int cursor_active; }; struct memcached_stat_st { diff --git a/lib/memcached_connect.c b/lib/memcached_connect.c index 116423ce..57274be2 100644 --- a/lib/memcached_connect.c +++ b/lib/memcached_connect.c @@ -13,6 +13,9 @@ memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_k if (ptr->hosts[server_key].fd == -1) { + /* Old connection junk still is in the structure */ + assert(ptr->hosts[server_key].stack_responses == 0); + if ((h= gethostbyname(ptr->hosts[server_key].hostname)) == NULL) { ptr->my_errno= h_errno; @@ -72,6 +75,7 @@ test_connect: } ptr->connected++; } + assert(ptr->hosts[server_key].stack_responses == 0); } return MEMCACHED_SUCCESS; diff --git a/lib/memcached_get.c b/lib/memcached_get.c index 4894b2a0..251cd592 100644 --- a/lib/memcached_get.c +++ b/lib/memcached_get.c @@ -85,14 +85,13 @@ static char *memcached_value_fetch(memcached_st *ptr, char *key, size_t *key_len /* We add two bytes so that we can walk the \r\n */ value= (char *)malloc(((*value_length) +2) * sizeof(char)); - memset(value, 0, ((*value_length) +2) * sizeof(char)); - if (!value) { *value_length= 0; *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; return NULL; } + memset(value, 0, ((*value_length) +2) * sizeof(char)); value_ptr= value; read_length= 0; @@ -164,6 +163,8 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length, *error= MEMCACHED_NOTFOUND; goto error; } + else if (*error == MEMCACHED_END) + assert(0); /* If this happens we have somehow messed up the fetch */ else if (*error == MEMCACHED_SUCCESS) { memcached_return rc; @@ -259,7 +260,10 @@ memcached_return memcached_mget(memcached_st *ptr, } memcached_string_free(ptr, string); cursor_key_exec[x]= NULL; /* Remove warning */ + ptr->hosts[x].cursor_active= 1; } + else + ptr->hosts[x].cursor_active= 0; } free(cursor_key_exec); @@ -277,16 +281,28 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, while (ptr->cursor_server < ptr->number_of_hosts) { + if (!ptr->hosts[ptr->cursor_server].cursor_active) + { + ptr->cursor_server++; + continue; + } + value_check= memcached_value_fetch(ptr, key, key_length, value_length, flags, error, 1, ptr->cursor_server); if (*error == MEMCACHED_NOTFOUND) ptr->cursor_server++; + else if (*error == MEMCACHED_END && *value_length == 0) + return NULL; + else if (*error == MEMCACHED_END) + assert(0); /* If this happens we have somehow messed up the fetch */ else if (*error != MEMCACHED_SUCCESS) return NULL; else return value_check; + } + *value_length= 0; return NULL; } diff --git a/lib/memcached_hosts.c b/lib/memcached_hosts.c index 64892212..0fcf4cdb 100644 --- a/lib/memcached_hosts.c +++ b/lib/memcached_hosts.c @@ -1,6 +1,15 @@ #include #include "common.h" +static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port) +{ + host->stack_responses= 0; + host->cursor_active= 0; + host->hostname= new_hostname; + host->port= port; + host->fd= -1; +} + memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) { unsigned int x; @@ -26,9 +35,11 @@ memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *l ptr->hosts[ptr->number_of_hosts].hostname= strdup(list[x].hostname); ptr->hosts[ptr->number_of_hosts].port= list[x].port; ptr->hosts[ptr->number_of_hosts].fd= list[x].fd; + ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses; + ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active; ptr->number_of_hosts++; } - memset(&ptr->hosts[ptr->number_of_hosts], 0, sizeof(memcached_server_st)); + host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0); return MEMCACHED_SUCCESS; } @@ -52,7 +63,7 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); if (!new_host_list) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - memset(&new_host_list[ptr->number_of_hosts], 0, sizeof(memcached_server_st)); + host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0); } else { @@ -60,7 +71,8 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne (memcached_server_st *)malloc(sizeof(memcached_server_st) * 2); if (!new_host_list) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - memset(new_host_list, 0, sizeof(memcached_server_st) * 2); + host_reset(&new_host_list[0], NULL, 0); + host_reset(&new_host_list[1], NULL, 0); } ptr->hosts= new_host_list; @@ -73,9 +85,7 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne memset(new_hostname, 0, strlen(hostname)+1); memcpy(new_hostname, hostname, strlen(hostname)); - ptr->hosts[ptr->number_of_hosts].hostname= new_hostname; - ptr->hosts[ptr->number_of_hosts].port= port; - ptr->hosts[ptr->number_of_hosts].fd= -1; + host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port); ptr->number_of_hosts++; LIBMEMCACHED_MEMCACHED_SERVER_ADD_END(); @@ -105,7 +115,7 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count); if (!new_host_list) goto error; - memset(&new_host_list[count-1], 0, sizeof(memcached_server_st)); + host_reset(&new_host_list[count-1], NULL, 0); } else { @@ -113,7 +123,8 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count); if (!new_host_list) goto error; - memset(new_host_list, 0, sizeof(memcached_server_st) * 2); + host_reset(&new_host_list[0], NULL, 0); + host_reset(&new_host_list[1], NULL, 0); } new_hostname= strdup(hostname); @@ -121,9 +132,7 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, if (!new_hostname) goto error; - new_host_list[count-2].hostname= new_hostname; - new_host_list[count-2].port= port; - new_host_list[count-2].fd= -1; + host_reset(&new_host_list[count-2], new_hostname, port); *error= MEMCACHED_SUCCESS; return new_host_list; diff --git a/lib/memcached_io.c b/lib/memcached_io.c index 2f86930e..5e05d2c5 100644 --- a/lib/memcached_io.c +++ b/lib/memcached_io.c @@ -9,53 +9,44 @@ ssize_t memcached_io_read(memcached_st *ptr, unsigned int server_key, char *buffer, size_t length) { - size_t x; char *buffer_ptr; buffer_ptr= buffer; - for (x= 0, buffer_ptr= buffer; - x < length; x++) + while (length) { if (!ptr->read_buffer_length) { - if (length > 1) - { + size_t data_read; - size_t data_read; - data_read= recv(ptr->hosts[server_key].fd, - buffer_ptr, - length - x, 0); - if (data_read == -1) - { - return -1; - } - if (data_read == 0) - return x; - - data_read+= x; - - return data_read; - } - else + while (1) { - size_t data_read; -try_again: - if (ptr->flags & MEM_NO_BLOCK) { - struct timeval local_tv; - fd_set set; - - memset(&local_tv, 0, sizeof(struct timeval)); - - local_tv.tv_sec= 0; - local_tv.tv_usec= 300; - - FD_ZERO(&set); - FD_SET(ptr->hosts[server_key].fd, &set); - - select(1, &set, NULL, NULL, &local_tv); + while (1) + { + int select_return; + struct timeval local_tv; + fd_set set; + + memset(&local_tv, 0, sizeof(struct timeval)); + + local_tv.tv_sec= 0; + local_tv.tv_usec= 300; + + FD_ZERO(&set); + FD_SET(ptr->hosts[server_key].fd, &set); + + select_return= select(1, &set, NULL, NULL, &local_tv); + + if (select_return == -1) + { + ptr->my_errno= errno; + return -1; + } + else if (!select_return) + break; + } } data_read= recv(ptr->hosts[server_key].fd, @@ -63,26 +54,34 @@ try_again: MEMCACHED_MAX_BUFFER, 0); if (data_read == -1) { - if (errno == EAGAIN) - goto try_again; - return -1; + switch (errno) + { + case EAGAIN: + break; + default: + { + ptr->my_errno= errno; + return -1; + } + } } - ptr->read_buffer_length= data_read; - ptr->read_ptr= ptr->read_buffer; + else if (data_read) + break; + /* If zero, just keep looping */ } - if (ptr->read_buffer_length == -1) - return -1; - if (ptr->read_buffer_length == 0) - return x; + ptr->read_buffer_length= data_read; + ptr->read_ptr= ptr->read_buffer; } + *buffer_ptr= *ptr->read_ptr; - buffer_ptr++; + length--; ptr->read_ptr++; ptr->read_buffer_length--; + buffer_ptr++; } - return length; + return (size_t)(buffer_ptr - buffer); } ssize_t memcached_io_write(memcached_st *ptr, unsigned int server_key, diff --git a/lib/memcached_quit.c b/lib/memcached_quit.c index d7a42315..2ceaa679 100644 --- a/lib/memcached_quit.c +++ b/lib/memcached_quit.c @@ -18,6 +18,7 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key) close(ptr->hosts[server_key].fd); ptr->hosts[server_key].fd= -1; ptr->hosts[server_key].stack_responses= 0; + ptr->hosts[server_key].cursor_active= 0; } ptr->connected--; diff --git a/lib/memcached_response.c b/lib/memcached_response.c index 10547504..d0962a2d 100644 --- a/lib/memcached_response.c +++ b/lib/memcached_response.c @@ -24,6 +24,7 @@ memcached_return memcached_response(memcached_st *ptr, max_messages= memcached_server_response_count(ptr, server_key); for (x= 0; x <= max_messages; x++) { + size_t total_length= 0; buffer_ptr= buffer; while (1) @@ -40,6 +41,9 @@ memcached_return memcached_response(memcached_st *ptr, break; else buffer_ptr++; + + total_length++; + assert(total_length < buffer_length); } if (memcached_server_response_count(ptr, server_key)) diff --git a/tests/test.c b/tests/test.c index 714cd891..047ed29a 100644 --- a/tests/test.c +++ b/tests/test.c @@ -208,6 +208,8 @@ void get_test3(memcached_st *memc) string= memcached_get(memc, key, strlen(key), &string_length, &flags, &rc); + WATCHPOINT_ERRNO(memc->my_errno); + WATCHPOINT_ERROR(rc); assert(rc == MEMCACHED_SUCCESS); assert(string); assert(string_length == value_length); @@ -570,8 +572,12 @@ int main(int argc, char *argv[]) { unsigned int x; char *server_list; + char *wildcard= NULL; memcached_server_st *servers; + if (argc == 2) + wildcard= argv[1]; + if (!(server_list= getenv("MEMCACHED_SERVERS"))) server_list= "localhost"; @@ -581,6 +587,16 @@ int main(int argc, char *argv[]) servers= memcached_servers_parse(server_list); assert(servers); + for (x= 0; x < memcached_server_list_count(servers); x++) + { + printf("\t%s : %u\n", servers[x].hostname, servers[x].port); + assert(servers[x].stack_responses == 0); + assert(servers[x].fd == -1); + assert(servers[x].cursor_active == 0); + } + + printf("\n"); + /* Clean the server before beginning testing */ test_st tests[] ={ {"flush", 0, flush_test }, @@ -617,6 +633,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nBlock tests\n\n"); for (x= 0; tests[x].function_name; x++) { + if (wildcard) + if (strcmp(wildcard, tests[x].function_name)) + continue; + memcached_st *memc; memcached_return rc; memc= memcached_create(NULL); @@ -625,6 +645,14 @@ int main(int argc, char *argv[]) rc= memcached_server_push(memc, servers); assert(rc == MEMCACHED_SUCCESS); + unsigned int loop; + for (loop= 0; loop < memcached_server_list_count(servers); loop++) + { + assert(memc->hosts[loop].stack_responses == 0); + assert(memc->hosts[loop].fd == -1); + assert(memc->hosts[loop].cursor_active == 0); + } + fprintf(stderr, "Testing %s", tests[x].function_name); tests[x].function(memc); fprintf(stderr, "\t\t\t\t\t[ ok ]\n"); @@ -635,6 +663,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nNonblock tests\n\n"); for (x= 0; tests[x].function_name; x++) { + if (wildcard) + if (strcmp(wildcard, tests[x].function_name)) + continue; + memcached_st *memc; memcached_return rc; memc= memcached_create(NULL); @@ -654,6 +686,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nTCP Nodelay tests\n\n"); for (x= 0; tests[x].function_name; x++) { + if (wildcard) + if (strcmp(wildcard, tests[x].function_name)) + continue; + memcached_st *memc; memcached_return rc; memc= memcached_create(NULL); @@ -674,6 +710,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nMD5 Hashing\n\n"); for (x= 0; tests[x].function_name; x++) { + if (wildcard) + if (strcmp(wildcard, tests[x].function_name)) + continue; + memcached_st *memc; memcached_return rc; memc= memcached_create(NULL); @@ -693,6 +733,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nUser Supplied tests\n\n"); for (x= 0; user_tests[x].function_name; x++) { + if (wildcard) + if (strcmp(wildcard, tests[x].function_name)) + continue; + memcached_st *memc; memcached_return rc; memc= memcached_create(NULL);