From: Brian Aker Date: Tue, 14 Jun 2011 11:41:17 +0000 (-0700) Subject: Merge in fix for additional logic for timeouts. X-Git-Tag: 0.51~4^2~17 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=805884743f76a5c4dad8ad20e6033630a92e71df;p=m6w6%2Flibmemcached Merge in fix for additional logic for timeouts. --- diff --git a/libmemcached/connect.cc b/libmemcached/connect.cc index 1d45ded1..707f7344 100644 --- a/libmemcached/connect.cc +++ b/libmemcached/connect.cc @@ -74,13 +74,13 @@ static memcached_return_t connect_poll(memcached_server_st *ptr) { return MEMCACHED_SUCCESS; } - else - { - return memcached_set_errno(*ptr, err, MEMCACHED_AT); - } + + return memcached_set_errno(*ptr, err, MEMCACHED_AT); } case 0: - return MEMCACHED_TIMEOUT; + { + return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT); + } default: // A real error occurred and we need to completely bail WATCHPOINT_ERRNO(get_socket_errno()); @@ -114,22 +114,19 @@ static memcached_return_t connect_poll(memcached_server_st *ptr) (void)closesocket(ptr->fd); ptr->fd= INVALID_SOCKET; + ptr->state= MEMCACHED_SERVER_STATE_NEW; - return MEMCACHED_ERRNO; + return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT); } } } // This should only be possible from ERESTART or EINTR; - ptr->cached_errno= get_socket_errno(); - - return MEMCACHED_ERRNO; + return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT); } static memcached_return_t set_hostinfo(memcached_server_st *server) { - char str_port[NI_MAXSERV]; - assert(! server->address_info); // We cover the case where a programming mistake has been made. if (server->address_info) { @@ -138,6 +135,7 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) server->address_info_next= NULL; } + char str_port[NI_MAXSERV]; int length= snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port); if (length >= NI_MAXSERV || length < 0) return MEMCACHED_FAILURE; @@ -175,7 +173,7 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_BADFLAGS)")); case EAI_MEMORY: - return memcached_set_error(*server, MEMCACHED_ERRNO, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_MEMORY)")); + return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_MEMORY)")); default: { @@ -185,17 +183,18 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) } } server->address_info_next= server->address_info; + server->state= MEMCACHED_SERVER_STATE_ADDRINFO; return MEMCACHED_SUCCESS; } -static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr) +static inline void set_socket_nonblocking(memcached_server_st *ptr) { #ifdef WIN32 u_long arg = 1; if (ioctlsocket(ptr->fd, FIONBIO, &arg) == SOCKET_ERROR) { - return memcached_set_errno(*ptr, get_socket_errno(), NULL); + memcached_set_errno(*ptr, get_socket_errno(), NULL); } #else int flags; @@ -203,12 +202,11 @@ static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr do { flags= fcntl(ptr->fd, F_GETFL, 0); - } - while (flags == -1 && (errno == EINTR || errno == EAGAIN)); + } while (flags == -1 && (errno == EINTR || errno == EAGAIN)); - unlikely (flags == -1) + if (flags == -1) { - return memcached_set_errno(*ptr, errno, NULL); + memcached_set_errno(*ptr, errno, NULL); } else if ((flags & O_NONBLOCK) == 0) { @@ -217,24 +215,22 @@ static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr do { rval= fcntl(ptr->fd, F_SETFL, flags | O_NONBLOCK); - } - while (rval == -1 && (errno == EINTR || errno == EAGAIN)); + } while (rval == -1 && (errno == EINTR || errno == EAGAIN)); unlikely (rval == -1) { - return memcached_set_errno(*ptr, errno, NULL); + memcached_set_errno(*ptr, errno, NULL); } } #endif - return MEMCACHED_SUCCESS; } -static memcached_return_t set_socket_options(memcached_server_st *ptr) +static void set_socket_options(memcached_server_st *ptr) { WATCHPOINT_ASSERT(ptr->fd != -1); if (ptr->type == MEMCACHED_CONNECTION_UDP) - return MEMCACHED_SUCCESS; + return; #ifdef HAVE_SNDTIMEO if (ptr->root->snd_timeout) @@ -248,8 +244,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime, (socklen_t)sizeof(struct timeval)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } #endif @@ -265,15 +259,13 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime, (socklen_t)sizeof(struct timeval)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } #endif #if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) { - int set = 1; + int set= 1; int error= setsockopt(ptr->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); // This is not considered a fatal error @@ -295,8 +287,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER, &linger, (socklen_t)sizeof(struct linger)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } if (ptr->root->flags.tcp_nodelay) @@ -307,8 +297,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_NODELAY, &flag, (socklen_t)sizeof(int)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } if (ptr->root->flags.tcp_keepalive) @@ -319,8 +307,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_KEEPALIVE, &flag, (socklen_t)sizeof(int)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } #ifdef TCP_KEEPIDLE @@ -331,8 +317,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_KEEPIDLE, &ptr->root->tcp_keepidle, (socklen_t)sizeof(int)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } #endif @@ -343,8 +327,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF, &ptr->root->send_size, (socklen_t)sizeof(int)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } if (ptr->root->recv_size > 0) @@ -354,13 +336,11 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr) error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVBUF, &ptr->root->recv_size, (socklen_t)sizeof(int)); WATCHPOINT_ASSERT(error == 0); - if (error) - return MEMCACHED_FAILURE; } /* libmemcached will always use nonblocking IO to avoid write deadlocks */ - return set_socket_nonblocking(ptr); + set_socket_nonblocking(ptr); } static memcached_return_t unix_socket_connect(memcached_server_st *ptr) @@ -379,25 +359,29 @@ static memcached_return_t unix_socket_connect(memcached_server_st *ptr) servAddr.sun_family= AF_UNIX; strncpy(servAddr.sun_path, ptr->hostname, sizeof(servAddr.sun_path)); /* Copy filename */ -test_connect: - if (connect(ptr->fd, - (struct sockaddr *)&servAddr, - sizeof(servAddr)) < 0) - { - switch (errno) + do { + if (connect(ptr->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { - case EINPROGRESS: - case EALREADY: - case EINTR: - goto test_connect; - case EISCONN: /* We were spinning waiting on connect */ - break; - default: - WATCHPOINT_ERRNO(errno); - ptr->cached_errno= errno; - return MEMCACHED_ERRNO; + switch (errno) + { + case EINPROGRESS: + case EALREADY: + case EINTR: + continue; + + case EISCONN: /* We were spinning waiting on connect */ + { + WATCHPOINT_ASSERT(0); // Programmer error + break; + } + + default: + WATCHPOINT_ERRNO(errno); + return memcached_set_errno(*ptr, errno, MEMCACHED_AT); + } } - } + } while (0); + ptr->state= MEMCACHED_SERVER_STATE_CONNECTED; WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET); @@ -417,6 +401,7 @@ static memcached_return_t network_connect(memcached_server_st *ptr) if (not ptr->address_info) { + WATCHPOINT_ASSERT(ptr->state == MEMCACHED_SERVER_STATE_NEW); memcached_return_t rc; uint32_t counter= 5; while (--counter) @@ -455,67 +440,87 @@ static memcached_return_t network_connect(memcached_server_st *ptr) return memcached_set_errno(*ptr, get_socket_errno(), NULL); } - (void)set_socket_options(ptr); + set_socket_options(ptr); /* connect to server */ if ((connect(ptr->fd, ptr->address_info_next->ai_addr, ptr->address_info_next->ai_addrlen) != SOCKET_ERROR)) { + ptr->state= MEMCACHED_SERVER_STATE_CONNECTED; break; // Success } /* An error occurred */ - ptr->cached_errno= get_socket_errno(); - switch (ptr->cached_errno) + switch (get_socket_errno()) { + case ETIMEDOUT: + timeout_error_occured= true; + break; + case EWOULDBLOCK: case EINPROGRESS: // nonblocking mode - first return case EALREADY: // nonblocking mode - subsequent returns { + ptr->state= MEMCACHED_SERVER_STATE_IN_PROGRESS; memcached_return_t rc= connect_poll(ptr); + if (memcached_success(rc)) + { + ptr->state= MEMCACHED_SERVER_STATE_CONNECTED; + return MEMCACHED_SUCCESS; + } + + // A timeout here is treated as an error, we will not retry if (rc == MEMCACHED_TIMEOUT) + { timeout_error_occured= true; - - if (rc == MEMCACHED_SUCCESS) - break; + } } + break; case EISCONN: // we are connected :-) + WATCHPOINT_ASSERT(0); // This is a programmer's error break; case EINTR: // Special case, we retry ai_addr (void)closesocket(ptr->fd); ptr->fd= INVALID_SOCKET; + ptr->state= MEMCACHED_SERVER_STATE_NEW; continue; default: - (void)closesocket(ptr->fd); - ptr->fd= INVALID_SOCKET; - ptr->address_info_next= ptr->address_info_next->ai_next; break; } + + (void)closesocket(ptr->fd); + ptr->fd= INVALID_SOCKET; + ptr->address_info_next= ptr->address_info_next->ai_next; } - if (ptr->fd == INVALID_SOCKET) - { - WATCHPOINT_STRING("Never got a good file descriptor"); + WATCHPOINT_ASSERT(ptr->fd == INVALID_SOCKET); - /* Failed to connect. schedule next retry */ - if (ptr->root->retry_timeout) + if (timeout_error_occured) + { + if (ptr->fd != INVALID_SOCKET) { - struct timeval next_time; - - if (gettimeofday(&next_time, NULL) == 0) - ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout; + (void)closesocket(ptr->fd); + ptr->fd= INVALID_SOCKET; } + } - if (timeout_error_occured) - return MEMCACHED_TIMEOUT; + WATCHPOINT_STRING("Never got a good file descriptor"); + /* Failed to connect. schedule next retry */ + if (ptr->root->retry_timeout) + { + struct timeval next_time; - return MEMCACHED_ERRNO; /* The last error should be from connect() */ + if (gettimeofday(&next_time, NULL) == 0) + ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout; } - return MEMCACHED_SUCCESS; /* The last error should be from connect() */ + if (timeout_error_occured) + return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT); + + return memcached_set_error(*ptr, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */ } void set_last_disconnected_host(memcached_server_write_instance_st self) diff --git a/libmemcached/delete.cc b/libmemcached/delete.cc index 1005cb90..1ae891a7 100644 --- a/libmemcached/delete.cc +++ b/libmemcached/delete.cc @@ -158,6 +158,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr, { if (send_length > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH) return MEMCACHED_WRITE_FAILURE; + if (send_length + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH) memcached_io_write(instance, NULL, 0, true); } @@ -216,6 +217,7 @@ static inline memcached_return_t binary_delete(memcached_st *ptr, size_t cmd_size= sizeof(request.bytes) + key_length; if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH) return MEMCACHED_WRITE_FAILURE; + if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH) memcached_io_write(instance, NULL, 0, true); } diff --git a/libmemcached/do.cc b/libmemcached/do.cc index 14824a64..854c6114 100644 --- a/libmemcached/do.cc +++ b/libmemcached/do.cc @@ -9,7 +9,7 @@ * */ -#include "common.h" +#include memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command, size_t command_length, bool with_flush) @@ -20,8 +20,9 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const vo WATCHPOINT_ASSERT(command_length); WATCHPOINT_ASSERT(command); - if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS) + if (memcached_failed(rc= memcached_connect(ptr))) { + WATCHPOINT_ASSERT(rc == memcached_last_error(ptr->root)); WATCHPOINT_ERROR(rc); return rc; } diff --git a/libmemcached/error.cc b/libmemcached/error.cc index b5e947a4..16608ff9 100644 --- a/libmemcached/error.cc +++ b/libmemcached/error.cc @@ -36,6 +36,7 @@ */ #include +#include #define MAX_ERROR_LENGTH 2048 struct memcached_error_t @@ -120,18 +121,21 @@ static void _set(memcached_st& memc, memcached_string_t *str, memcached_return_t memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, const char *str, size_t length) { + assert(rc != MEMCACHED_ERRNO); memcached_string_t tmp= { str, length }; return memcached_set_error(memc, rc, at, tmp); } memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at, const char *str, size_t length) { + assert(rc != MEMCACHED_ERRNO); memcached_string_t tmp= { str, length }; return memcached_set_error(self, rc, at, tmp); } memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, memcached_string_t& str) { + assert(rc != MEMCACHED_ERRNO); if (memcached_success(rc)) return MEMCACHED_SUCCESS; @@ -142,6 +146,7 @@ memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at, memcached_string_t& str) { + assert(rc != MEMCACHED_ERRNO); if (memcached_success(rc)) return MEMCACHED_SUCCESS; @@ -171,6 +176,7 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at) { + assert(rc != MEMCACHED_ERRNO); if (memcached_success(rc)) return MEMCACHED_SUCCESS; @@ -189,6 +195,7 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu memcached_return_t memcached_set_error(memcached_st& self, memcached_return_t rc, const char *at) { + assert(rc != MEMCACHED_ERRNO); if (memcached_success(rc)) return MEMCACHED_SUCCESS; diff --git a/libmemcached/io.cc b/libmemcached/io.cc index fb4b0022..40aaec20 100644 --- a/libmemcached/io.cc +++ b/libmemcached/io.cc @@ -295,8 +295,6 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr, } else if (data_read == SOCKET_ERROR) { - ptr->cached_errno= get_socket_errno(); - memcached_return_t rc= MEMCACHED_ERRNO; switch (get_socket_errno()) { case EWOULDBLOCK: @@ -307,8 +305,10 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr, #ifdef TARGET_OS_LINUX case ERESTART: #endif - if ((rc= io_wait(ptr, MEM_READ)) == MEMCACHED_SUCCESS) + if (memcached_success(io_wait(ptr, MEM_READ))) + { continue; + } /* fall through */ @@ -316,7 +316,7 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr, { memcached_quit_server(ptr, true); *nread= -1; - return memcached_set_error(*ptr, rc, MEMCACHED_AT); + return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT); } } } @@ -497,6 +497,8 @@ memcached_return_t memcached_io_close(memcached_server_write_instance_st ptr) { WATCHPOINT_ERRNO(get_socket_errno()); } + ptr->state= MEMCACHED_SERVER_STATE_NEW; + ptr->fd= INVALID_SOCKET; return MEMCACHED_SUCCESS; } diff --git a/libmemcached/memcached.cc b/libmemcached/memcached.cc index f2e8993b..ee95eaa1 100644 --- a/libmemcached/memcached.cc +++ b/libmemcached/memcached.cc @@ -311,9 +311,8 @@ void memcached_free(memcached_st *ptr) memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source) { memcached_return_t rc= MEMCACHED_SUCCESS; - memcached_st *new_clone; - if (source == NULL) + if (not source) return memcached_create(clone); if (clone && memcached_is_allocated(clone)) @@ -321,9 +320,9 @@ memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source) return NULL; } - new_clone= memcached_create(clone); + memcached_st *new_clone= memcached_create(clone); - if (new_clone == NULL) + if (not new_clone) return NULL; new_clone->flags= source->flags; diff --git a/libmemcached/quit.cc b/libmemcached/quit.cc index fb045ce1..b44b508e 100644 --- a/libmemcached/quit.cc +++ b/libmemcached/quit.cc @@ -101,7 +101,6 @@ void memcached_quit_server(memcached_server_st *ptr, bool io_death) memcached_io_close(ptr); } - ptr->fd= INVALID_SOCKET; ptr->io_bytes_sent= 0; ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0); ptr->read_buffer_length= 0; diff --git a/libmemcached/server.cc b/libmemcached/server.cc index 57540ccf..ea88967d 100644 --- a/libmemcached/server.cc +++ b/libmemcached/server.cc @@ -69,6 +69,8 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root, self->address_info= NULL; self->address_info_next= NULL; + self->state= MEMCACHED_SERVER_STATE_NEW; + if (root) { self->next_retry= root->retry_timeout; @@ -80,13 +82,13 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root, self->root= root; self->limit_maxbytes= 0; - if (hostname == NULL) + if (hostname) { - self->hostname[0]= 0; + strncpy(self->hostname, hostname, NI_MAXHOST - 1); } else { - strncpy(self->hostname, hostname, NI_MAXHOST - 1); + self->hostname[0]= 0; } } @@ -294,8 +296,7 @@ void memcached_server_list_free(memcached_server_list_st self) } } - memcached_st *root= self->root; - libmemcached_free(root, self); + libmemcached_free(self->root, self); } uint32_t memcached_servers_set_count(memcached_server_st *servers, uint32_t count) diff --git a/libmemcached/server.h b/libmemcached/server.h index d4005f89..aeb493fe 100644 --- a/libmemcached/server.h +++ b/libmemcached/server.h @@ -38,6 +38,13 @@ #pragma once +enum memcached_server_state_t { + MEMCACHED_SERVER_STATE_NEW, + MEMCACHED_SERVER_STATE_ADDRINFO, + MEMCACHED_SERVER_STATE_IN_PROGRESS, + MEMCACHED_SERVER_STATE_CONNECTED +}; + struct memcached_server_st { struct { bool is_allocated:1; @@ -53,6 +60,7 @@ struct memcached_server_st { uint32_t io_bytes_sent; /* # bytes sent since last read */ uint32_t server_failure_counter; uint32_t weight; + enum memcached_server_state_t state; struct { uint32_t read; uint32_t write; diff --git a/libmemcached/stats.cc b/libmemcached/stats.cc index d5d34a84..5a2013e8 100644 --- a/libmemcached/stats.cc +++ b/libmemcached/stats.cc @@ -577,14 +577,11 @@ char ** memcached_stat_get_keys(memcached_st *ptr, return list; } -void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat) +void memcached_stat_free(const memcached_st *, memcached_stat_st *memc_stat) { - if (not ptr) - return; - + WATCHPOINT_ASSERT(memc_stat); // Be polite, but when debugging catch this as an error if (not memc_stat) { - WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */ return; } @@ -594,7 +591,7 @@ void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat) return; } - libmemcached_free(ptr, memc_stat); + libmemcached_free(NULL, memc_stat); } static memcached_return_t call_stat_fn(memcached_st *ptr, diff --git a/libmemcached/storage.cc b/libmemcached/storage.cc index 006393c4..c6d653c1 100644 --- a/libmemcached/storage.cc +++ b/libmemcached/storage.cc @@ -68,7 +68,6 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, bool to_write; size_t write_length; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - uint32_t server_key; memcached_server_write_instance_st instance; WATCHPOINT_ASSERT(!(value == NULL && value_length > 0)); @@ -85,7 +84,7 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, if (ptr->flags.verify_key && (memcached_key_test((const char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) return MEMCACHED_BAD_KEY_PROVIDED; - server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length); + uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length); instance= memcached_server_instance_fetch(ptr, server_key); WATCHPOINT_SET(instance->io_wait_count.read= 0); @@ -142,13 +141,12 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, buffer_ptr++; write_length= (size_t)(buffer_ptr - buffer); - int check_length; - check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer), - "%u %llu %lu%s\r\n", - flags, - (unsigned long long)expiration, (unsigned long)value_length, - ptr->flags.no_reply ? " noreply" : ""); - if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer) || check_length < 0) + int check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer), + "%u %llu %lu%s\r\n", + flags, + (unsigned long long)expiration, (unsigned long)value_length, + ptr->flags.no_reply ? " noreply" : ""); + if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -size_t(buffer_ptr - buffer) || check_length < 0) { rc= MEMCACHED_WRITE_FAILURE; memcached_io_reset(instance); @@ -162,16 +160,17 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, if (ptr->flags.use_udp && ptr->flags.buffer_requests) { - size_t cmd_size= write_length + value_length + 2; + size_t cmd_size= write_length + value_length +2; if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH) - return MEMCACHED_WRITE_FAILURE; + return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT); + if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH) memcached_io_write(instance, NULL, 0, true); } if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) { - rc= MEMCACHED_WRITE_FAILURE; + rc= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT); } else { diff --git a/libmemcached/strerror.cc b/libmemcached/strerror.cc index 48a970aa..d3781824 100644 --- a/libmemcached/strerror.cc +++ b/libmemcached/strerror.cc @@ -47,9 +47,9 @@ const char *memcached_strerror(memcached_st *, memcached_return_t rc) return "FAILURE"; case MEMCACHED_HOST_LOOKUP_FAILURE: // getaddrinfo only return "getaddrinfo() HOSTNAME LOOKUP FAILURE"; - case MEMCACHED_CONNECTION_FAILURE: // DEPRECATED + case MEMCACHED_CONNECTION_FAILURE: return "CONNECTION FAILURE"; - case MEMCACHED_CONNECTION_BIND_FAILURE: + case MEMCACHED_CONNECTION_BIND_FAILURE: // DEPRECATED, see MEMCACHED_HOST_LOOKUP_FAILURE return "CONNECTION BIND FAILURE"; case MEMCACHED_READ_FAILURE: return "READ FAILURE"; diff --git a/libtest/server.c b/libtest/server.c index 8c6d296c..1c3ea100 100644 --- a/libtest/server.c +++ b/libtest/server.c @@ -258,12 +258,15 @@ void server_startup(server_startup_st *construct) switch (errno) { default: - fprintf(stderr, "%s -> fopen(%s)\n", construct->pid_file[x], strerror(errno)); + fprintf(stderr, "Could not open pid file %s -> fopen(%s) -> %s:%d\n", construct->pid_file[x], strerror(errno), + __FILE__, __LINE__); abort(); case ENOENT: case EINTR: case EACCES: + case EINPROGRESS: break; + case ENOTCONN: continue; } diff --git a/libtest/test.h b/libtest/test.h index 0493f310..29959283 100644 --- a/libtest/test.h +++ b/libtest/test.h @@ -228,6 +228,15 @@ do \ } \ } while (0) +#define test_skip(A,B) \ +do \ +{ \ + if ((A) != (B)) \ + { \ + return TEST_SKIPPED; \ + } \ +} while (0) + #define test_compare_got(A,B,C) \ do \ { \ diff --git a/tests/mem_functions.cc b/tests/mem_functions.cc index 093721b5..c74b6b1e 100644 --- a/tests/mem_functions.cc +++ b/tests/mem_functions.cc @@ -1809,10 +1809,7 @@ static test_return_t mget_execute(memcached_st *memc) static test_return_t key_setup(memcached_st *memc) { - (void)memc; - - if (pre_binary(memc) != TEST_SUCCESS) - return TEST_SKIPPED; + test_skip(TEST_SUCCESS, pre_binary(memc)); global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0); @@ -1881,22 +1878,17 @@ static test_return_t version_string_test(memcached_st *memc) static test_return_t get_stats(memcached_st *memc) { - char **stat_list; - char **ptr; memcached_return_t rc; - memcached_stat_st *memc_stat; - - memc_stat= memcached_stat(memc, NULL, &rc); - test_true(rc == MEMCACHED_SUCCESS); - test_true(rc == MEMCACHED_SUCCESS); + memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc); + test_compare(MEMCACHED_SUCCESS, rc); test_true(memc_stat); for (uint32_t x= 0; x < memcached_server_count(memc); x++) { - stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc); - test_true(rc == MEMCACHED_SUCCESS); - for (ptr= stat_list; *ptr; ptr++); + char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc); + test_compare(MEMCACHED_SUCCESS, rc); + for (char **ptr= stat_list; *ptr; ptr++); free(stat_list); } @@ -3411,8 +3403,7 @@ static test_return_t get_read(memcached_st *memc) static test_return_t mget_read(memcached_st *memc) { - if (not libmemcached_util_version_check(memc, 1, 4, 4)) - return TEST_SKIPPED; + test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4))); memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count); @@ -3434,8 +3425,7 @@ static test_return_t mget_read(memcached_st *memc) static test_return_t mget_read_result(memcached_st *memc) { - if (not libmemcached_util_version_check(memc, 1, 4, 4)) - return TEST_SKIPPED; + test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4))); memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count); @@ -3460,9 +3450,7 @@ static test_return_t mget_read_result(memcached_st *memc) static test_return_t mget_read_function(memcached_st *memc) { - - if (not libmemcached_util_version_check(memc, 1, 4, 4)) - return TEST_SKIPPED; + test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4))); memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count); @@ -3730,7 +3718,7 @@ static test_return_t pre_sasl(memcached_st *memc) static test_return_t pre_replication(memcached_st *memc) { - test_true(TEST_SUCCESS == pre_binary(memc)); + test_skip(TEST_SUCCESS, pre_binary(memc)); /* * Make sure that we store the item on all servers @@ -3747,7 +3735,7 @@ static test_return_t pre_replication(memcached_st *memc) static test_return_t pre_replication_noblock(memcached_st *memc) { - test_compare(TEST_SUCCESS, pre_replication(memc)); + test_skip(TEST_SUCCESS, pre_replication(memc)); return pre_nonblock(memc); } @@ -4768,7 +4756,6 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc) { (void)memc; memcached_st *tl_memc_h; - memcached_server_st *servers; const char *key= "MemcachedLives"; size_t len; @@ -4778,7 +4765,8 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc) // Create a handle. tl_memc_h= memcached_create(NULL); - servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist + memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist + test_true(servers); memcached_server_push(tl_memc_h, servers); memcached_server_list_free(servers); @@ -4786,7 +4774,7 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc) value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc); test_false(value); - test_true(len == 0); + test_compare(0, len); test_false(rc == MEMCACHED_SUCCESS); memcached_free(tl_memc_h); @@ -5437,7 +5425,7 @@ static test_return_t test_multiple_get_last_disconnect(memcached_st *) { const char *msg= memcached_strerror(memc, memcached_return_t(x)); memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0); - test_compare_got(MEMCACHED_WRITE_FAILURE, ret, memcached_strerror(NULL, ret)); + test_compare_got(MEMCACHED_CONNECTION_FAILURE, ret, memcached_last_error_message(memc)); memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc); test_true(disconnected_server); diff --git a/tests/parser.cc b/tests/parser.cc index 13561bcc..bb2de83f 100644 --- a/tests/parser.cc +++ b/tests/parser.cc @@ -566,7 +566,7 @@ test_return_t regression_bug_71231153_connect(memcached_st *) char *value= memcached_get(memc, memcached_literal_param("test"), &value_len, NULL, &rc); test_false(value); test_compare(0, value_len); - test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(NULL, rc)); + test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_strerror(NULL, rc)); memcached_free(memc); }