Addition for wildcard tests.
Fix for multi, aka three, hosts for key reads.
unsigned int port;
int fd;
unsigned int stack_responses;
+ unsigned int cursor_active;
};
struct memcached_stat_st {
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;
}
ptr->connected++;
}
+ assert(ptr->hosts[server_key].stack_responses == 0);
}
return MEMCACHED_SUCCESS;
/* 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;
*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;
}
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);
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;
}
#include <memcached.h>
#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;
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;
}
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
{
(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;
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();
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
{
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);
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;
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,
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,
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--;
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)
break;
else
buffer_ptr++;
+
+ total_length++;
+ assert(total_length < buffer_length);
}
if (memcached_server_response_count(ptr, server_key))
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);
{
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";
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 },
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);
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");
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);
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);
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);
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);