AC_CHECK_HEADERS([stddef.h])
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([sasl/sasl.h])
+AC_CHECK_HEADERS([execinfo.h])
+AC_CHECK_HEADERS([cxxabi.h],
+ AC_DEFINE([HAVE_CXXABI_H], [1], [Have cxxabi.h]),
+ AC_DEFINE([HAVE_CXXABI_H], [0], [Have cxxabi.h]))
AC_CXX_HEADER_STDCXX_98
AC_FUNC_ALLOCA
AC_C_VOLATILE
AC_C_RESTRICT
+AX_CXX_GCC_ABI_DEMANGLE
+
dnl The sasl functions should only be visible if we build with sasl support
AS_IF([test "x$ac_cv_sasl" = "xyes"],
[
{ \
if (not (__expr)) \
{ \
- fprintf(stderr, "\nAssertion \"%s\" failed for function \"%s\" likely for %s, at %s:%d\n", #__expr, __func__, (#__mesg), __FILE__, __LINE__);\
+ fprintf(stderr, "\n%s:%d Assertion \"%s\" failed for function \"%s\" likely for %s\n", __FILE__, __LINE__, #__expr, __func__, (#__mesg));\
custom_backtrace(); \
abort(); \
} \
#include <cstring>
#include <cstdlib>
-#ifdef __GNUC__
-#ifdef HAVE_BACKTRACE
+#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
+#endif
+
+#ifdef HAVE_CXXABI_H
#include <cxxabi.h>
-#endif // HAVE_BACKTRACE
-#endif // __GNUC__
+#endif
+#ifdef HAVE_GCC_ABI_DEMANGLE
+#define USE_DEMANGLE 1
+#else
+#define USE_DEMANGLE 0
+#endif
void custom_backtrace(void)
{
-#ifdef __GNUC__
-#ifdef HAVE_BACKTRACE
+#ifdef HAVE_EXECINFO_H
void *array[50];
size_t size= backtrace(array, 50);
char **strings= backtrace_symbols(array, size);
+ if (strings == NULL)
+ {
+ return;
+ }
+
fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size);
- for (size_t x= 1; x < size; x++)
+ char *named_function= (char *)::realloc(NULL, 1024);
+
+ if (named_function == NULL)
{
- size_t sz= 200;
- char *function= (char *)malloc(sz);
- char *begin= 0;
- char *end= 0;
+ ::free(strings);
+ return;
+ }
- for (char *j = strings[x]; *j; ++j)
+ for (size_t x= 1; x < size; x++)
+ {
+ if (USE_DEMANGLE)
{
- if (*j == '(') {
- begin = j;
+ size_t sz= 200;
+ char *named_function_ptr= (char *)::realloc(named_function, sz);
+ if (named_function_ptr == NULL)
+ {
+ continue;
}
- else if (*j == '+') {
- end = j;
+ named_function= named_function_ptr;
+
+ char *begin_name= 0;
+ char *begin_offset= 0;
+ char *end_offset= 0;
+
+ for (char *j= strings[x]; *j; ++j)
+ {
+ if (*j == '(')
+ {
+ begin_name= j;
+ }
+ else if (*j == '+')
+ {
+ begin_offset= j;
+ }
+ else if (*j == ')' and begin_offset)
+ {
+ end_offset= j;
+ break;
+ }
}
- }
- if (begin && end)
- {
- begin++;
- *end= '\0';
- int status;
- char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
- if (ret)
+ if (begin_name and begin_offset and end_offset and begin_name < begin_offset)
{
- function= ret;
+ *begin_name++= '\0';
+ *begin_offset++= '\0';
+ *end_offset= '\0';
+
+ int status;
+ char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status);
+ if (ret) // realloc()'ed string
+ {
+ named_function= ret;
+ fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset);
+ }
+ else
+ {
+ fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset);
+ }
}
else
{
- strncpy(function, begin, sz);
- strncat(function, "()", sz);
- function[sz-1] = '\0';
+ fprintf(stderr, " %s\n", strings[x]);
}
- fprintf(stderr, "%s\n", function);
}
else
{
- fprintf(stderr, "%s\n", strings[x]);
+ fprintf(stderr, " unmangled: %s\n", strings[x]);
}
- free(function);
}
-
- free (strings);
-#endif // HAVE_BACKTRACE
-#endif // __GNUC__
+ ::free(named_function);
+ ::free(strings);
+#endif // HAVE_EXECINFO_H
}
#pragma once
-LIBMEMCACHED_LOCAL
void custom_backtrace(void);
socklen_t sock_length= sizeof(int);
if (ptr->send_size != -1) // If value is -1 then we are using the default
+ {
return (uint64_t) ptr->send_size;
+ }
memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, 0);
if (instance->write_buffer_offset != 0)
{
- if (instance->fd == -1 &&
+ if (instance->fd == INVALID_SOCKET and
(ret= memcached_connect(instance)) != MEMCACHED_SUCCESS)
{
WATCHPOINT_ERROR(ret);
char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
if (ptr->flags.no_block)
+ {
(void)memcached_io_write(instance, NULL, 0, true);
+ }
while(memcached_server_response_count(instance))
(void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result);
if (ptr->fd == INVALID_SOCKET)
{
+#if 0
assert_msg(int(ptr->state) <= int(MEMCACHED_SERVER_STATE_ADDRINFO), "Programmer error, invalid socket state");
+#endif
return MEMCACHED_CONNECTION_FAILURE;
}
-#include "common.h"
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <libmemcached/common.h>
+
memcached_return_t memcached_purge(memcached_server_write_instance_st ptr)
{
so we need to be able stop any recursion.. */
memcached_set_purging(root, true);
- WATCHPOINT_ASSERT(ptr->fd != -1);
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
/* Force a flush of the buffer to ensure that we don't have the n-1 pending
requests buffered up.. */
if (memcached_io_write(ptr, NULL, 0, true) == -1)
return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
}
- WATCHPOINT_ASSERT(ptr->fd != -1);
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
uint32_t no_msg= memcached_server_response_count(ptr) - 1;
if (no_msg > 0)
* The only kind of errors I care about if is I'm out of sync with the
* protocol or have problems reading data from the network..
*/
- if (rc== MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_UNKNOWN_READ_FAILURE)
+ if (rc== MEMCACHED_PROTOCOL_ERROR or rc == MEMCACHED_UNKNOWN_READ_FAILURE or rc == MEMCACHED_READ_FAILURE)
{
WATCHPOINT_ERROR(rc);
ret= rc;
{
rc = (*cb.callback[y])(ptr->root, result_ptr, cb.context);
if (rc != MEMCACHED_SUCCESS)
+ {
break;
+ }
}
}
}
rc= textual_read_one_response(ptr, buffer, buffer_length, result);
}
- unlikely(rc == MEMCACHED_UNKNOWN_READ_FAILURE or
- rc == MEMCACHED_PROTOCOL_ERROR or
- rc == MEMCACHED_CLIENT_ERROR or
- rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
+ 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)
{
memcached_io_reset(ptr);
}
{
return MEMCACHED_END;
}
- else if (buffer[1] == 'R' and buffer[2] == 'R' and buffer[3] == 'O' and buffer[4] == 'R')
+ else if (buffer[1] == 'R' and buffer[2] == 'O' and buffer[3] == 'T' and buffer[4] == 'O' and buffer[5] == 'C' and buffer[6] == 'O' and buffer[7] == 'L'
+ and buffer[8] == '_'
+ and buffer[9] == 'E' and buffer[10] == 'R' and buffer[11] == 'R' and buffer[12] == 'O' and buffer[13] == 'R')
{
return MEMCACHED_PROTOCOL_ERROR;
}
case PROTOCOL_BINARY_CMD_INCREMENT:
case PROTOCOL_BINARY_CMD_DECREMENT:
{
- if (bodylen != sizeof(uint64_t) || buffer_length != sizeof(uint64_t))
+ if (bodylen != sizeof(uint64_t) or buffer_length != sizeof(uint64_t))
{
return MEMCACHED_PROTOCOL_ERROR;
}
self->number_of_hosts= 0;
self->cursor_active= 0;
self->port= port;
- self->fd= -1;
+ self->fd= INVALID_SOCKET;
self->io_bytes_sent= 0;
self->server_failure_counter= 0;
self->server_failure_counter_query_id= 0;
static memcached_server_st *_server_create(memcached_server_st *self, const memcached_st *memc)
{
- if (not self)
+ if (self == NULL)
{
self= libmemcached_xmalloc(memc, struct memcached_server_st);
- if (not self)
+ if (self == NULL)
{
return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */
}
_server_init(self, const_cast<memcached_st *>(memc), hostname, port, weight, type);
-
- if (memc and memcached_is_udp(memc))
- {
- self->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
- memcached_io_init_udp_header(self, 0);
- }
-
if (memc)
{
set_hostinfo(self);
memcached_string_t _hostname= { memcached_string_make_from_cstr(hostname) };
/* @todo Check return type */
- if (not __server_create_with(NULL, &new_host_list[count-1], _hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET))
+ if (__server_create_with(NULL, &new_host_list[count-1], _hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET) == NULL)
{
*error= memcached_set_errno(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
return NULL;
*error= MEMCACHED_SUCCESS;
- if (not memcmp("pid", key, sizeof("pid") -1))
+ if (memcmp("pid", key, sizeof("pid") -1) == 0)
{
length= snprintf(buffer, SMALL_STRING_LEN,"%lld", (signed long long)memc_stat->pid);
}
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
*
- * Use and distribution licensed under the BSD license. See
- * the COPYING file in the parent directory for full text.
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker All rights reserved.
*
- * Summary: Storage related functions, aka set, replace,..
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
#include <libmemcached/common.h>
enum memcached_storage_action_t {
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cxx_gcc_abi_demangle.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_GCC_ABI_DEMANGLE
+#
+# DESCRIPTION
+#
+# If the compiler supports GCC C++ ABI name demangling (has header
+# cxxabi.h and abi::__cxa_demangle() function), define
+# HAVE_GCC_ABI_DEMANGLE
+#
+# Adapted from AX_CXX_RTTI by Luc Maisonobe
+#
+# LICENSE
+#
+# Copyright (c) 2008 Neil Ferguson <nferguso@eso.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 9
+
+AC_DEFUN([AX_CXX_GCC_ABI_DEMANGLE],
+[AC_CACHE_CHECK(whether the compiler supports GCC C++ ABI name demangling,
+ax_cv_cxx_gcc_abi_demangle,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <typeinfo>
+#include <cxxabi.h>
+#include <cstdlib>
+#include <string>
+
+template<typename TYPE>
+class A {};
+],[A<int> instance;
+int status = 0;
+char* c_name = 0;
+
+c_name = abi::__cxa_demangle(typeid(instance).name(), 0, 0, &status);
+
+std::string name(c_name);
+::free(c_name);
+
+return name == "A<int>";
+],
+ ax_cv_cxx_gcc_abi_demangle=yes, ax_cv_cxx_gcc_abi_demangle=no)
+ AC_LANG_RESTORE
+])
+if test "$ax_cv_cxx_gcc_abi_demangle" = yes; then
+ AC_DEFINE(HAVE_GCC_ABI_DEMANGLE,1,
+ [define if the compiler supports GCC C++ ABI name demangling])
+fi
+])
#define GLOBAL_COUNT 10000
#define GLOBAL2_COUNT 100
#define SERVERS_TO_CREATE 5
-static uint32_t global_count;
+static uint32_t global_count= GLOBAL2_COUNT;
static pairs_st *global_pairs;
static const char *global_keys[GLOBAL_COUNT];
{
unsigned int check_execute= execute_set(memc, global_pairs, global_count);
- test_compare(check_execute, global_count);
+ test_compare(global_count, check_execute);
return TEST_SUCCESS;
}