static inline bool memcached_fatal(memcached_return_t rc)
{
- return (rc != MEMCACHED_SUCCESS &&
+ return (
+ rc != MEMCACHED_BUFFERED &&
+ rc != MEMCACHED_DATA_EXISTS &&
+ rc != MEMCACHED_DELETED &&
+ rc != MEMCACHED_E2BIG &&
rc != MEMCACHED_END &&
- rc != MEMCACHED_STORED &&
+ rc != MEMCACHED_ITEM &&
+ rc != MEMCACHED_NOTFOUND &&
+ rc != MEMCACHED_NOTSTORED &&
+ rc != MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE &&
rc != MEMCACHED_STAT &&
- rc != MEMCACHED_DELETED &&
- rc != MEMCACHED_BUFFERED &&
+ rc != MEMCACHED_STORED &&
+ rc != MEMCACHED_SUCCESS &&
rc != MEMCACHED_VALUE);
}
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+ return rc;
}
uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+ return rc;
}
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+ return rc;
}
uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+ return rc;
}
uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
extern "C" {
#endif
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_connect(memcached_server_write_instance_st ptr);
-
LIBMEMCACHED_LOCAL
memcached_return_t run_distribution(memcached_st *ptr);
return memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
}
-memcached_return_t set_hostinfo(memcached_server_st *server)
+static memcached_return_t set_hostinfo(memcached_server_st *server)
{
+ assert(server->type != MEMCACHED_CONNECTION_UNIX_SOCKET);
if (server->address_info)
{
freeaddrinfo(server->address_info);
return MEMCACHED_SUCCESS;
}
-memcached_return_t memcached_connect(memcached_server_write_instance_st server)
+static memcached_return_t _memcached_connect(memcached_server_write_instance_st server, const bool set_last_disconnected)
{
if (server->fd != INVALID_SOCKET)
{
return memcached_set_error(*server, MEMCACHED_INVALID_HOST_PROTOCOL, MEMCACHED_AT, memcached_literal_param("SASL is not supported for UDP connections"));
}
+ if (server->hostname[0] == '/')
+ {
+ server->type= MEMCACHED_CONNECTION_UNIX_SOCKET;
+ }
+
/* We need to clean up the multi startup piece */
switch (server->type)
{
memcached_mark_server_as_clean(server);
return rc;
}
-
- set_last_disconnected_host(server);
- if (memcached_has_current_error(*server))
+ else if (set_last_disconnected)
{
- memcached_mark_server_for_timeout(server);
- assert(memcached_failed(memcached_server_error_return(server)));
- }
- else
- {
- memcached_set_error(*server, rc, MEMCACHED_AT);
- memcached_mark_server_for_timeout(server);
- }
+ set_last_disconnected_host(server);
+ if (memcached_has_current_error(*server))
+ {
+ memcached_mark_server_for_timeout(server);
+ assert(memcached_failed(memcached_server_error_return(server)));
+ }
+ else
+ {
+ memcached_set_error(*server, rc, MEMCACHED_AT);
+ memcached_mark_server_for_timeout(server);
+ }
- LIBMEMCACHED_MEMCACHED_CONNECT_END();
+ LIBMEMCACHED_MEMCACHED_CONNECT_END();
- if (in_timeout)
- {
- return memcached_set_error(*server, MEMCACHED_SERVER_TEMPORARILY_DISABLED, MEMCACHED_AT);
+ if (in_timeout)
+ {
+ char buffer[1024];
+ int snprintf_length= snprintf(buffer, sizeof(buffer), "%s:%d", server->hostname, int(server->port));
+ return memcached_set_error(*server, MEMCACHED_SERVER_TEMPORARILY_DISABLED, MEMCACHED_AT, buffer, snprintf_length);
+ }
}
return rc;
}
+
+memcached_return_t memcached_connect_try(memcached_server_write_instance_st server)
+{
+ return _memcached_connect(server, false);
+}
+
+memcached_return_t memcached_connect(memcached_server_write_instance_st server)
+{
+ return _memcached_connect(server, true);
+}
#pragma once
-memcached_return_t set_hostinfo(memcached_server_st *server);
+memcached_return_t memcached_connect_try(memcached_server_write_instance_st ptr);
+memcached_return_t memcached_connect(memcached_server_write_instance_st ptr);
+
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+ return rc;
}
if (expiration)
msg.msg_iov= (struct iovec*)vector;
msg.msg_iovlen= count;
- if (::sendmsg(instance->fd, &msg, 0) < 1)
+ uint32_t retry= 5;
+ while (--retry)
{
- return memcached_set_error(*instance, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ ssize_t sendmsg_length= ::sendmsg(instance->fd, &msg, 0);
+ if (sendmsg_length > 0)
+ {
+ break;
+ }
+ else if (sendmsg_length < 0)
+ {
+ if (errno == EMSGSIZE)
+ {
+ return memcached_set_error(*instance, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ }
+
+ perror(__func__);
+ return memcached_set_errno(*instance, errno, MEMCACHED_AT);
+ }
}
return MEMCACHED_SUCCESS;
#include <libmemcached/common.h>
-static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callback, void *context, uint32_t number_of_callbacks)
+static memcached_return_t ascii_dump(memcached_st *memc, memcached_dump_fn *callback, void *context, uint32_t number_of_callbacks)
{
- memcached_return_t rc= MEMCACHED_SUCCESS;
-
- for (uint32_t server_key= 0; server_key < memcached_server_count(ptr); server_key++)
+ for (uint32_t server_key= 0; server_key < memcached_server_count(memc); server_key++)
{
- memcached_server_write_instance_st instance;
- instance= memcached_server_instance_fetch(ptr, server_key);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
+ bool exit_slab_loop= false;
/* MAX_NUMBER_OF_SLAB_CLASSESdefined to 200 in Memcached 1.4.10 */
- for (uint32_t x= 0; x < 200; x++)
+ for (uint32_t x= 0; x < 200 and (exit_slab_loop == false); x++)
{
char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
int buffer_length= snprintf(buffer, sizeof(buffer), "%u", x);
- if (buffer_length >= MEMCACHED_DEFAULT_COMMAND_SIZE or buffer_length < 0)
+ if (size_t(buffer_length) >= sizeof(buffer) or buffer_length < 0)
{
- return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
+ return memcached_set_error(*memc, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
}
{ memcached_literal_param(" 0 0\r\n") }
};
- rc= memcached_vdo(instance, vector, 3, true);
-
- if (rc != MEMCACHED_SUCCESS)
+ memcached_return_t vdo_rc;
+ if (memcached_success((vdo_rc= memcached_vdo(instance, vector, 3, true))))
{
- goto error;
- }
-
- while (1)
- {
- uint32_t callback_counter;
- rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
-
- if (rc == MEMCACHED_ITEM)
+ while (1)
{
- char *string_ptr, *end_ptr;
+ memcached_return_t response_rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
+ fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, response_rc));
+ if (response_rc == MEMCACHED_ITEM)
+ {
+ char *string_ptr, *end_ptr;
- string_ptr= buffer;
- string_ptr+= 5; /* Move past ITEM */
+ string_ptr= buffer;
+ string_ptr+= 5; /* Move past ITEM */
- for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++) {} ;
+ for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++) {} ;
- char *key= string_ptr;
- key[(size_t)(end_ptr-string_ptr)]= 0;
+ char *key= string_ptr;
+ key[(size_t)(end_ptr-string_ptr)]= 0;
- for (callback_counter= 0; callback_counter < number_of_callbacks; callback_counter++)
- {
- rc= (*callback[callback_counter])(ptr, key, (size_t)(end_ptr-string_ptr), context);
- if (rc != MEMCACHED_SUCCESS)
+ for (uint32_t callback_counter= 0; callback_counter < number_of_callbacks; callback_counter++)
{
- break;
+ memcached_return_t callback_rc= (*callback[callback_counter])(memc, key, (size_t)(end_ptr-string_ptr), context);
+ if (callback_rc != MEMCACHED_SUCCESS)
+ {
+ // @todo build up a message for the error from the value
+ memcached_set_error(*instance, callback_rc, MEMCACHED_AT);
+ break;
+ }
}
}
- }
- else if (rc == MEMCACHED_END)
- {
- break;
- }
- else if (rc == MEMCACHED_SERVER_ERROR or rc == MEMCACHED_CLIENT_ERROR)
- {
- /* If we try to request stats cachedump for a slab class that is too big
- * the server will return an incorrect error message:
- * "MEMCACHED_SERVER_ERROR failed to allocate memory"
- * This isn't really a fatal error, so let's just skip it. I want to
- * fix the return value from the memcached server to a CLIENT_ERROR,
- * so let's add support for that as well right now.
- */
- rc= MEMCACHED_END;
- break;
- }
- else
- {
- goto error;
+ else if (response_rc == MEMCACHED_END)
+ {
+ // No additional items were found
+ exit_slab_loop= true;
+ break;
+ }
+ else if (response_rc == MEMCACHED_SERVER_ERROR or response_rc == MEMCACHED_CLIENT_ERROR)
+ {
+ /* If we try to request stats cachedump for a slab class that is too big
+ * the server will return an incorrect error message:
+ * "MEMCACHED_SERVER_ERROR failed to allocate memory"
+ * This isn't really a fatal error, so let's just skip it. I want to
+ * fix the return value from the memcached server to a CLIENT_ERROR,
+ * so let's add support for that as well right now.
+ */
+ exit_slab_loop= true;
+ break;
+ }
+ else
+ {
+ memcached_set_error(*instance, response_rc, MEMCACHED_AT);
+ exit_slab_loop= true;
+ break;
+ }
}
}
+ else
+ {
+ exit_slab_loop= true;
+ memcached_set_error(*instance, vdo_rc, MEMCACHED_AT);
+ }
+ fprintf(stderr, "Was able to request %u slab\n", x);
}
}
-error:
- if (rc == MEMCACHED_END)
- {
- return MEMCACHED_SUCCESS;
- }
- else
- {
- return rc;
- }
+ return memcached_has_current_error(*memc) ? MEMCACHED_SOME_ERRORS : MEMCACHED_SUCCESS;
}
memcached_return_t memcached_dump(memcached_st *ptr, memcached_dump_fn *callback, void *context, uint32_t number_of_callbacks)
server.error_messages= error;
}
+#if 0
+static int error_log_fd= -1;
+#endif
+
static void _set(memcached_st& memc, memcached_string_t *str, memcached_return_t &rc, const char *at, int local_errno= 0)
{
if (memc.error_messages && memc.error_messages->query_id != memc.query_id)
if (str and str->size and local_errno)
{
- error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "%s(%s), %.*s -> %s",
+ error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "(%lu) %s(%s), %.*s -> %s",
+ long(error->root),
memcached_strerror(&memc, rc),
errmsg_ptr,
memcached_string_printf(*str), at);
}
else if (local_errno)
{
- error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "%s(%s) -> %s",
+ error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "(%lu) %s(%s) -> %s",
+ long(error->root),
memcached_strerror(&memc, rc),
errmsg_ptr,
at);
}
else if (rc == MEMCACHED_PARSE_ERROR and str and str->size)
{
- error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "%.*s -> %s",
+ error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "(%lu) %.*s -> %s",
+ long(error->root),
int(str->size), str->c_str, at);
}
else if (str and str->size)
{
- error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "%s, %.*s -> %s",
+ error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "(%lu) %s, %.*s -> %s",
+ long(error->root),
memcached_strerror(&memc, rc),
int(str->size), str->c_str, at);
}
else
{
- error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "%s -> %s",
+ error->size= (int)snprintf(error->message, MAX_ERROR_LENGTH, "(%lu) %s -> %s",
+ long(error->root),
memcached_strerror(&memc, rc), at);
}
error->next= memc.error_messages;
memc.error_messages= error;
+
+#if 0
+ if (error_log_fd == -1)
+ {
+// unlink("/tmp/libmemcachd.log");
+ if ((error_log_fd= open("/tmp/libmemcachd.log", O_CREAT | O_WRONLY | O_APPEND, 0644)) < 0)
+ {
+ perror("open");
+ error_log_fd= -1;
+ }
+ }
+ ::write(error_log_fd, error->message, error->size);
+ ::write(error_log_fd, "\n", 1);
+#endif
}
memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, const char *str, size_t length)
memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, memcached_string_t& str)
{
assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
- if (memcached_success(rc))
+ if (memcached_fatal(rc) == false)
{
return rc;
}
{
assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
assert_msg(rc != MEMCACHED_SOME_ERRORS, "Programmer error, MEMCACHED_SOME_ERRORS was about to be set on a memcached_server_st");
- if (memcached_success(rc))
+ if (memcached_fatal(rc) == false)
{
return rc;
}
memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at)
{
assert_msg(rc != MEMCACHED_SOME_ERRORS, "Programmer error, MEMCACHED_SOME_ERRORS was about to be set on a memcached_server_st");
- if (memcached_success(rc))
+ if (memcached_fatal(rc) == false)
{
return rc;
}
memcached_return_t memcached_set_error(memcached_st& self, memcached_return_t rc, const char *at)
{
assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
- if (memcached_success(rc))
+ if (memcached_fatal(rc) == false)
{
return rc;
}
memcached_string_t error_host= { hostname_port_message, size };
memcached_return_t rc= MEMCACHED_ERRNO;
- if (not self.root)
+ if (self.root == NULL)
+ {
return rc;
+ }
_set(*self.root, &error_host, rc, at, local_errno);
_set(self, (*self.root));
memcached_string_t error_host= { hostname_port_message, size };
memcached_return_t rc= MEMCACHED_ERRNO;
- if (not self.root)
+ if (self.root == NULL)
+ {
return rc;
+ }
_set(*self.root, &error_host, rc, at, local_errno);
_set(self, (*self.root));
}
if (not memc->error_messages)
+ {
return MEMCACHED_SUCCESS;
+ }
return memc->error_messages->rc;
}
}
if (not server->error_messages)
+ {
return memcached_strerror(server->root, MEMCACHED_SUCCESS);
+ }
if (not server->error_messages->size)
+ {
return memcached_strerror(server->root, server->error_messages->rc);
+ }
return server->error_messages->message;
}
};
/* Send command header */
- memcached_return_t rc= memcached_vdo(instance, vector, 9, true);
- if (rc == MEMCACHED_SUCCESS)
+ memcached_return_t rc;
+ if (memcached_fatal(rc= memcached_vdo(instance, vector, 9, true)))
{
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
- rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
-
- if (rc == MEMCACHED_NOTSTORED)
- {
- rc= MEMCACHED_SUCCESS;
- }
-
- if (rc == MEMCACHED_STORED)
- {
- rc= MEMCACHED_NOTFOUND;
- }
+ return rc;
}
- if (rc == MEMCACHED_WRITE_FAILURE)
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
+
+ if (rc == MEMCACHED_NOTSTORED)
{
- memcached_io_reset(instance);
+ rc= MEMCACHED_SUCCESS;
+ }
+
+ if (rc == MEMCACHED_STORED)
+ {
+ rc= MEMCACHED_NOTFOUND;
}
return rc;
/* write the header */
memcached_return_t rc;
- if ((rc= memcached_vdo(instance, vector, 4, true)) != MEMCACHED_SUCCESS)
+ if (memcached_fatal(rc= memcached_vdo(instance, vector, 4, true)))
{
- memcached_io_reset(instance);
- return (rc == MEMCACHED_SUCCESS) ? MEMCACHED_WRITE_FAILURE : rc;
+ return rc;
}
rc= memcached_response(instance, NULL, 0, NULL);
if (rc == MEMCACHED_SUCCESS)
+ {
rc= MEMCACHED_NOTFOUND;
+ }
if (rc == MEMCACHED_DATA_EXISTS)
+ {
rc= MEMCACHED_SUCCESS;
+ }
return rc;
}
if (memcached_is_udp(memc))
{
- return MEMCACHED_NOT_SUPPORTED;
+ return memcached_set_error(*memc, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT);
}
uint32_t server_key= memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
- memcached_server_write_instance_st instance;
- instance= memcached_server_instance_fetch(memc, server_key);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
- if (memc->flags.binary_protocol)
+ if (memcached_is_binary(memc))
{
- return binary_exist(memc, instance, key, key_length);
+ rc= binary_exist(memc, instance, key, key_length);
}
else
{
- return ascii_exist(memc, instance, key, key_length);
+ rc= ascii_exist(memc, instance, key, key_length);
}
+
+ if (memcached_fatal(rc))
+ {
+ memcached_io_reset(instance);
+ }
+
+ return rc;
}
/* This is for historical reasons */
if (*error == MEMCACHED_END)
+ {
*error= MEMCACHED_NOTFOUND;
+ }
if (value == NULL)
{
memcached_return_t rc= ptr->get_key_failure(ptr, key, key_length, &ptr->result);
/* On all failure drop to returning NULL */
- if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED)
+ if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED)
{
if (rc == MEMCACHED_BUFFERED)
{
uint64_t latch; /* We use latch to track the state of the original socket */
latch= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS);
if (latch == 0)
+ {
memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
+ }
rc= memcached_set(ptr, key, key_length,
(memcached_result_value(&ptr->result)),
if (memcached_failed(memcached_key_test(*ptr, keys, key_length, number_of_keys)))
{
- return memcached_set_error(*ptr, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("A bad key value was provided"));
+ return memcached_last_error(ptr);
}
bool is_group_key_set= false;
if (sent_length == SOCKET_ERROR)
{
- memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
#if 0 // @todo I should look at why we hit this bit of code hard frequently
WATCHPOINT_ERRNO(get_socket_errno());
WATCHPOINT_NUMBER(get_socket_errno());
{
if (keys == NULL or key_length == NULL)
{
- return memcached_set_error(memc, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT);
+ return memcached_set_error(memc, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("Key was NULL or length of key was zero."));
}
// If we don't need to verify the key, or we are using the binary protoocol,
memcached_return_t rc= memcached_validate_key_length(*(key_length +x), false /* memc.flags.binary_protocol */);
if (memcached_failed(rc))
{
- return rc;
+ return memcached_set_error(memc, rc, MEMCACHED_AT, memcached_literal_param("Key provided was too long."));
}
}
memcached_return_t rc= memcached_validate_key_length(*(key_length + x), false);
if (memcached_failed(rc))
{
- return rc;
+ return memcached_set_error(memc, rc, MEMCACHED_AT, memcached_literal_param("Key provided was too long."));
}
for (size_t y= 0; y < *(key_length + x); y++)
{
if ((isgraph(keys[x][y])) == 0)
{
- return MEMCACHED_BAD_KEY_PROVIDED;
+ return memcached_set_error(memc, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("Key provided had invalid character."));
}
}
}
if (memcached_failed(memcached_key_test(*self, (const char **)&key, &key_length, 1)))
{
self->flags.verify_key= orig;
- return memcached_set_error(*self, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT);
+ return memcached_last_error(self);
}
self->flags.verify_key= orig;
return MEMCACHED_SERVER_ERROR;
}
- if (total_read > memcached_literal_param_size("SERVER_ERROR object too large for cache") and
+ if (total_read >= memcached_literal_param_size("SERVER_ERROR object too large for cache") and
(memcmp(buffer, memcached_literal_param("SERVER_ERROR object too large for cache")) == 0))
{
return MEMCACHED_E2BIG;
}
+ if (total_read >= memcached_literal_param_size("SERVER_ERROR out of memory storing object") and
+ (memcmp(buffer, memcached_literal_param("SERVER_ERROR out of memory storing object")) == 0))
+ {
+ return MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE;
+ }
+
// Move past the basic error message and whitespace
char *startptr= buffer + memcached_literal_param_size("SERVER_ERROR");
if (startptr[0] == ' ')
assert(rc != MEMCACHED_PROTOCOL_ERROR);
}
- if (rc == MEMCACHED_UNKNOWN_READ_FAILURE or
- rc == MEMCACHED_READ_FAILURE or
- rc == MEMCACHED_PROTOCOL_ERROR or
- rc == MEMCACHED_CLIENT_ERROR or
- rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
+ if (memcached_fatal(rc))
{
memcached_io_reset(ptr);
}
memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr, numeric_value);
// @TODO should we return an error on another but a bad read case?
- if (rc != MEMCACHED_END and
- rc != MEMCACHED_STORED and
- rc != MEMCACHED_SUCCESS and
- rc != MEMCACHED_STAT and
+ if (
+ rc != MEMCACHED_DATA_EXISTS and
rc != MEMCACHED_DELETED and
+ rc != MEMCACHED_E2BIG and
+ rc != MEMCACHED_END and
+ rc != MEMCACHED_ITEM and
rc != MEMCACHED_NOTFOUND and
rc != MEMCACHED_NOTSTORED and
- rc != MEMCACHED_DATA_EXISTS)
+ rc != MEMCACHED_SERVER_ERROR and
+ rc != MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE and
+ rc != MEMCACHED_STAT and
+ rc != MEMCACHED_STORED and
+ rc != MEMCACHED_SUCCESS and
+ rc != MEMCACHED_VALUE
+ )
{
memcached_result_free(junked_result_ptr);
return rc;
if (memc)
{
- set_hostinfo(self);
+ memcached_connect_try(self);
}
return self;
if (need && need > (size_t)(string->current_size - (size_t)(string->end - string->string)))
{
size_t current_offset= (size_t) (string->end - string->string);
- size_t adjust;
- size_t new_size;
/* This is the block multiplier. To keep it larger and surive division errors we must round it up */
- adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / MEMCACHED_BLOCK_SIZE;
+ size_t adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / MEMCACHED_BLOCK_SIZE;
adjust++;
- new_size= sizeof(char) * (size_t)((adjust * MEMCACHED_BLOCK_SIZE) + string->current_size);
+ size_t new_size= sizeof(char) * (size_t)((adjust * MEMCACHED_BLOCK_SIZE) + string->current_size);
/* Test for overflow */
if (new_size < need)
- return memcached_set_error(*string->root, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+ {
+ char error_message[1024];
+ int error_message_length= snprintf(error_message, sizeof(error_message),"Needed %ld, got %ld", (long)need, (long)new_size);
+ return memcached_set_error(*string->root, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, error_message, error_message_length);
+ }
char *new_value= libmemcached_xrealloc(string->root, string->string, new_size, char);
#include "tests/libmemcached-1.0/dump.h"
static memcached_return_t callback_dump_counter(const memcached_st *,
- const char *,
- size_t ,
+ const char *key,
+ size_t length,
void *context)
{
size_t *counter= (size_t *)context;
+ std::cerr.write(key, length);
+ std::cerr << std::endl;
+
+
*counter= *counter +1;
return MEMCACHED_SUCCESS;
memcached_dump_fn callbacks[1];
callbacks[0]= &callback_dump_counter;
- test_compare_hint(MEMCACHED_SUCCESS, memcached_dump(memc, callbacks, &count, 1), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_dump(memc, callbacks, &count, 1), memcached_last_error_message(memc));
+
+ return TEST_SUCCESS;
+}
+
+#define memcached_dump_TEST2_COUNT 64
+test_return_t memcached_dump_TEST2(memcached_st *memc)
+{
+ test_skip(false, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
+
+ /* The dump test relies on there being at least 32 items in memcached */
+ for (uint32_t x= 0; x < memcached_dump_TEST2_COUNT; x++)
+ {
+ char key[1024];
+
+ int length= snprintf(key, sizeof(key), "%s%u", __func__, x);
+
+ test_true(length > 0);
+
+ test_compare_hint(MEMCACHED_SUCCESS,
+ memcached_set(memc, key, length,
+ NULL, 0, // Zero length values
+ time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+ }
+ memcached_quit(memc);
+
+ size_t count= 0;
+ memcached_dump_fn callbacks[1];
+ callbacks[0]= &callback_dump_counter;
+
+ test_compare_got(MEMCACHED_SUCCESS,
+ memcached_dump(memc, callbacks, &count, 1),
+ memcached_last_error_message(memc));
+
+#if 0
+ test_compare(size_t(memcached_dump_TEST2_COUNT), count);
+#endif
return TEST_SUCCESS;
}
#pragma once
test_return_t memcached_dump_TEST(memcached_st *);
+test_return_t memcached_dump_TEST2(memcached_st *);
test_return_t memcached_exist_SUCCESS(memcached_st *memc)
{
- test_compare(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("frog"), 0, 0, 0, 0));
- test_compare(MEMCACHED_SUCCESS, memcached_exist(memc, test_literal_param("frog")));
- test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, test_literal_param("frog"), 0));
- test_compare(MEMCACHED_NOTFOUND, memcached_exist(memc, test_literal_param("frog")));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("frog"), 0, 0, 0, 0), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_exist(memc, test_literal_param("frog")), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_delete(memc, test_literal_param("frog"), 0), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_NOTFOUND, memcached_exist(memc, test_literal_param("frog")), memcached_last_error_message(memc));
return TEST_SUCCESS;
}
test_return_t memcached_exist_by_key_SUCCESS(memcached_st *memc)
{
- test_compare(MEMCACHED_SUCCESS, memcached_set_by_key(memc, test_literal_param("master"), test_literal_param("frog"), 0, 0, 0, 0));
- test_compare(MEMCACHED_SUCCESS, memcached_exist_by_key(memc, test_literal_param("master"), test_literal_param("frog")));
- test_compare(MEMCACHED_SUCCESS, memcached_delete_by_key(memc, test_literal_param("master"), test_literal_param("frog"), 0));
- test_compare(MEMCACHED_NOTFOUND, memcached_exist_by_key(memc, test_literal_param("master"), test_literal_param("frog")));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_set_by_key(memc, test_literal_param("master"), test_literal_param("frog"), 0, 0, 0, 0), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_exist_by_key(memc, test_literal_param("master"), test_literal_param("frog")), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_delete_by_key(memc, test_literal_param("master"), test_literal_param("frog"), 0), memcached_last_error_message(memc));
+ test_compare_got(MEMCACHED_NOTFOUND, memcached_exist_by_key(memc, test_literal_param("master"), test_literal_param("frog")), memcached_last_error_message(memc));
return TEST_SUCCESS;
}
test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
/* All keys are valid in the binary protocol (except for length) */
- if (not memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
+ if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == false)
{
uint64_t before_query_id= memcached_query_id(memc_clone);
{
static test_return_t analyzer_test(memcached_st *memc)
{
- memcached_return_t rc;
memcached_analysis_st *report;
+ memcached_return_t rc;
memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
test_compare(MEMCACHED_SUCCESS, rc);
return TEST_SUCCESS;
}
-/* Count the objects */
-
-static test_return_t dump_test(memcached_st *memc)
-{
- /* No support for Binary protocol yet */
- test_skip(false, memc->flags.binary_protocol);
-
- test_compare(TEST_SUCCESS, set_test3(memc));
-
- // confirm_key_count() call dump
- size_t counter= confirm_key_count(memc);
-
- /* We may have more then 32 if our previous flush has not completed */
- test_true(counter >= 32);
-
- return TEST_SUCCESS;
-}
-
static test_return_t util_version_test(memcached_st *memc)
{
test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
}
- (void)snprintf(k, sizeof(k), "%037u", 251U);
- len= strlen(k);
+ len= snprintf(k, sizeof(k), "%037u", 251U);
memcached_return_t rc= memcached_delete(memc, k, len, 0);
test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
static test_return_t regression_bug_463297(memcached_st *memc)
{
+ test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
+
+ // Since we blocked timed delete, this test is no longer valid.
+#if 0
memcached_st *memc_clone= memcached_clone(NULL, memc);
test_true(memc_clone);
test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
}
memcached_free(memc_clone);
+#endif
+
return TEST_SUCCESS;
}
test_true(keys[x]);
memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
- test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+ test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
}
for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
{"connection_test", false, (test_callback_fn*)connection_test},
{"callback_test", false, (test_callback_fn*)callback_test},
{"userdata_test", false, (test_callback_fn*)userdata_test},
- {"set", false, (test_callback_fn*)set_test },
- {"set2", false, (test_callback_fn*)set_test2 },
- {"set3", false, (test_callback_fn*)set_test3 },
- {"dump", true, (test_callback_fn*)dump_test},
+ {"memcached_set()", false, (test_callback_fn*)set_test },
+ {"memcached_set() 2", false, (test_callback_fn*)set_test2 },
+ {"memcached_set() 3", false, (test_callback_fn*)set_test3 },
{"add", true, (test_callback_fn*)add_test },
{"memcached_fetch_result(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
{"replace", true, (test_callback_fn*)replace_test },
{"memcached_exist_by_key(MEMCACHED_SUCCESS)", true, (test_callback_fn*)memcached_exist_by_key_SUCCESS },
{"memcached_touch", 0, (test_callback_fn*)test_memcached_touch},
{"memcached_touch_with_prefix", 0, (test_callback_fn*)test_memcached_touch_by_key},
- {"memcached_dump()", 0, (test_callback_fn*)memcached_dump_TEST },
+ {"memcached_dump() no data", true, (test_callback_fn*)memcached_dump_TEST },
+ {"memcached_dump() with data", true, (test_callback_fn*)memcached_dump_TEST2 },
{0, 0, 0}
};