From: Brian Aker Date: Sat, 2 Apr 2011 22:27:03 +0000 (-0700) Subject: This cleans up some accidental linking we were getting with curses. X-Git-Tag: 0.51~15^2~54 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=5ba395ad3a28f000bdabc7312dcee483c14d996e;p=m6w6%2Flibmemcached This cleans up some accidental linking we were getting with curses. This also modifies the behavior of DNS caching such that we walk the hosts and can move to a new host. It also removes any chance of us leaking the DNS information. --- diff --git a/libmemcached/connect.c b/libmemcached/connect.c index 58a6cfd2..5e0c046b 100644 --- a/libmemcached/connect.c +++ b/libmemcached/connect.c @@ -86,10 +86,15 @@ static memcached_return_t connect_poll(memcached_server_st *ptr) static memcached_return_t set_hostinfo(memcached_server_st *server) { - struct addrinfo *ai; struct addrinfo hints; char str_port[NI_MAXSERV]; - uint32_t counter= 5; + + if (server->address_info) + { + freeaddrinfo(server->address_info); + server->address_info= NULL; + server->address_info_next= NULL; + } int length= snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port); if (length >= NI_MAXSERV || length < 0) @@ -97,7 +102,9 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) memset(&hints, 0, sizeof(hints)); - // hints.ai_family= AF_INET; +#if 0 + hints.ai_family= AF_INET; +#endif if (server->type == MEMCACHED_CONNECTION_UDP) { hints.ai_protocol= IPPROTO_UDP; @@ -109,9 +116,10 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) hints.ai_protocol= IPPROTO_TCP; } + uint32_t counter= 5; while (--counter) { - int e= getaddrinfo(server->hostname, str_port, &hints, &ai); + int e= getaddrinfo(server->hostname, str_port, &hints, &server->address_info); if (e == 0) { @@ -137,12 +145,7 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) } } - if (server->address_info) - { - freeaddrinfo(server->address_info); - server->address_info= NULL; - } - server->address_info= ai; + server->address_info_next= server->address_info; return MEMCACHED_SUCCESS; } @@ -370,34 +373,29 @@ static memcached_return_t network_connect(memcached_server_st *ptr) { bool timeout_error_occured= false; - WATCHPOINT_ASSERT(ptr->fd == INVALID_SOCKET); WATCHPOINT_ASSERT(ptr->cursor_active == 0); - if (! ptr->options.sockaddr_inited || (!(ptr->root->flags.use_cache_lookups))) + if (! ptr->address_info) { - memcached_return_t rc; - - rc= set_hostinfo(ptr); + memcached_return_t rc= set_hostinfo(ptr); if (rc != MEMCACHED_SUCCESS) return rc; - ptr->options.sockaddr_inited= true; } - struct addrinfo *use= ptr->address_info; /* Create the socket */ - while (use != NULL) + while (ptr->address_info_next && ptr->fd == INVALID_SOCKET) { /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */ - if (ptr->type == MEMCACHED_CONNECTION_UDP && use->ai_family != AF_INET) + if (ptr->type == MEMCACHED_CONNECTION_UDP && ptr->address_info_next->ai_family != AF_INET) { - use= use->ai_next; + ptr->address_info_next= ptr->address_info_next->ai_next; continue; } - if ((ptr->fd= socket(use->ai_family, - use->ai_socktype, - use->ai_protocol)) < 0) + if ((ptr->fd= socket(ptr->address_info_next->ai_family, + ptr->address_info_next->ai_socktype, + ptr->address_info_next->ai_protocol)) < 0) { ptr->cached_errno= get_socket_errno(); WATCHPOINT_ERRNO(get_socket_errno()); @@ -407,40 +405,43 @@ static memcached_return_t network_connect(memcached_server_st *ptr) (void)set_socket_options(ptr); /* connect to server */ - if ((connect(ptr->fd, use->ai_addr, use->ai_addrlen) != SOCKET_ERROR)) + if ((connect(ptr->fd, ptr->address_info_next->ai_addr, ptr->address_info_next->ai_addrlen) != SOCKET_ERROR)) { break; // Success } /* An error occurred */ ptr->cached_errno= get_socket_errno(); - if (ptr->cached_errno == EWOULDBLOCK || - ptr->cached_errno == EINPROGRESS || /* nonblocking mode - first return, */ - ptr->cached_errno == EALREADY) /* nonblocking mode - subsequent returns */ + switch (ptr->cached_errno) { - memcached_return_t rc; - rc= connect_poll(ptr); + case EWOULDBLOCK: + case EINPROGRESS: // nonblocking mode - first return + case EALREADY: // nonblocking mode - subsequent returns + { + memcached_return_t rc; + rc= connect_poll(ptr); - if (rc == MEMCACHED_TIMEOUT) - timeout_error_occured= true; + if (rc == MEMCACHED_TIMEOUT) + timeout_error_occured= true; - if (rc == MEMCACHED_SUCCESS) - break; - } - else if (get_socket_errno() == EISCONN) /* we are connected :-) */ - { + if (rc == MEMCACHED_SUCCESS) + break; + } + + case EISCONN: // we are connected :-) break; - } - else if (get_socket_errno() == EINTR) // Special case, we retry ai_addr - { + + case EINTR: // Special case, we retry ai_addr (void)closesocket(ptr->fd); ptr->fd= INVALID_SOCKET; continue; - } - (void)closesocket(ptr->fd); - ptr->fd= INVALID_SOCKET; - use= use->ai_next; + default: + (void)closesocket(ptr->fd); + ptr->fd= INVALID_SOCKET; + ptr->address_info_next= ptr->address_info_next->ai_next; + break; + } } if (ptr->fd == INVALID_SOCKET) diff --git a/libmemcached/memcached.c b/libmemcached/memcached.c index 149437af..3d2539eb 100644 --- a/libmemcached/memcached.c +++ b/libmemcached/memcached.c @@ -55,7 +55,6 @@ static const memcached_st global_copy= { .reuse_memory= false, .support_cas= false, .tcp_nodelay= false, - .use_cache_lookups= false, .use_sort_hosts= false, .use_udp= false, .verify_key= false, diff --git a/libmemcached/memcached.hpp b/libmemcached/memcached.hpp index f9d5756c..55f96c7e 100644 --- a/libmemcached/memcached.hpp +++ b/libmemcached/memcached.hpp @@ -12,6 +12,7 @@ * @brief Libmemcached C++ interface */ +#pragma once #ifndef LIBMEMCACHEDPP_H #define LIBMEMCACHEDPP_H diff --git a/libmemcached/server.c b/libmemcached/server.c index 97b0b27c..7b9b2eef 100644 --- a/libmemcached/server.c +++ b/libmemcached/server.c @@ -12,13 +12,12 @@ /* This is a partial implementation for fetching/creating memcached_server_st objects. */ -#include "common.h" +#include static inline void _server_init(memcached_server_st *self, const memcached_st *root, const char *hostname, in_port_t port, uint32_t weight, memcached_connection_t type) { - self->options.sockaddr_inited= false; self->options.is_shutting_down= false; self->number_of_hosts= 0; self->cursor_active= 0; @@ -42,6 +41,7 @@ static inline void _server_init(memcached_server_st *self, const memcached_st *r self->read_data_length= 0; self->write_buffer_offset= 0; self->address_info= NULL; + self->address_info_next= NULL; if (root) { diff --git a/libmemcached/server.h b/libmemcached/server.h index aadd690f..b0872014 100644 --- a/libmemcached/server.h +++ b/libmemcached/server.h @@ -17,7 +17,6 @@ struct memcached_server_st { struct { bool is_allocated:1; bool is_initialized:1; - bool sockaddr_inited:1; bool is_shutting_down:1; } options; uint32_t number_of_hosts; @@ -46,6 +45,7 @@ struct memcached_server_st { size_t read_data_length; size_t write_buffer_offset; struct addrinfo *address_info; + struct addrinfo *address_info_next; time_t next_retry; const memcached_st *root; uint64_t limit_maxbytes; diff --git a/libtest/server.c b/libtest/server.c index c96ffb51..31238fe6 100644 --- a/libtest/server.c +++ b/libtest/server.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,27 @@ static void global_sleep(void) #endif } +static bool wait_for_file(const char *filename) +{ + uint32_t timeout= 6; + uint32_t waited; + uint32_t this_wait; + uint32_t retry; + + for (waited= 0, retry= 1; ; retry++, waited+= this_wait) + { + if ((! access(filename, R_OK)) || (waited >= timeout)) + { + return true; + } + + this_wait= retry * retry / 3 + 1; + sleep(this_wait); + } + + return false; +} + static void kill_file(const char *file_buffer) { FILE *fp; @@ -179,7 +201,21 @@ void server_startup(server_startup_st *construct) } fclose(file); } - global_sleep(); + switch (errno) + { + default: + fprintf(stderr, "%s\n", strerror(errno)); + abort(); + case ENOENT: + case EINTR: + case EACCES: + break; + } + + if (! wait_for_file(buffer)) + { + abort(); + } } bool was_started= false; diff --git a/m4/pandora_drizzle_build.m4 b/m4/pandora_drizzle_build.m4 deleted file mode 100644 index 54f946f1..00000000 --- a/m4/pandora_drizzle_build.m4 +++ /dev/null @@ -1,77 +0,0 @@ -dnl Copyright (C) 2009 Sun Microsystems, Inc. -dnl This file is free software; Sun Microsystems, Inc. -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Check for all of the headers and libs that Drizzle needs. We check all -dnl of these for plugins too, to ensure that all of the appropriate defines -dnl are set. - -AC_DEFUN([PANDORA_DRIZZLE_BUILD],[ - - AC_STRUCT_TM - - AC_FUNC_ALLOCA - AC_FUNC_UTIME_NULL - AC_FUNC_VPRINTF - - PANDORA_WORKING_FDATASYNC - - AC_CHECK_FUNCS(\ - gethrtime \ - setupterm \ - backtrace \ - backtrace_symbols \ - backtrace_symbols_fd) - - AC_HEADER_STAT - AC_HEADER_DIRENT - AC_HEADER_STDC - AC_HEADER_SYS_WAIT - AC_HEADER_STDBOOL - - AC_CHECK_HEADERS(sys/types.h sys/fpu.h fpu_control.h ieeefp.h) - AC_CHECK_HEADERS(select.h sys/select.h) - AC_CHECK_HEADERS(utime.h sys/utime.h ) - AC_CHECK_HEADERS(synch.h sys/mman.h) - AC_CHECK_HEADERS(sched.h) - AC_CHECK_HEADERS(sys/prctl.h) - AC_CHECK_HEADERS(execinfo.h) - AC_CHECK_HEADERS(locale.h) - AC_CHECK_HEADERS(termcap.h termio.h termios.h asm/termbits.h) - AC_CHECK_HEADERS(paths.h) - - - #-------------------------------------------------------------------- - # Check for system libraries. Adds the library to $LIBS - # and defines HAVE_LIBM etc - #-------------------------------------------------------------------- - - # For the sched_yield() function on Solaris - AC_CHECK_FUNC(sched_yield, [], - [AC_CHECK_LIB(posix4, [sched_yield], - [AC_DEFINE(HAVE_SCHED_YIELD, 1, [Have sched_yield function]) LIBS="$LIBS -lposix4"])]) - - AS_IF([test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"],[ - AC_CHECK_FUNC(gtty, [], [AC_CHECK_LIB(compat, gtty)]) - ]) - - AC_CHECK_HEADERS([curses.h term.h],[],[],[[ - #ifdef HAVE_CURSES_H - # include - #endif - ]]) - AC_CHECK_TYPES([uint, ulong]) - - PANDORA_REQUIRE_BISON - - PANDORA_CXX_DEMANGLE - PANDORA_REQUIRE_BOOST([1.38]) - PANDORA_REQUIRE_BOOST_PROGRAM_OPTIONS - PANDORA_REQUIRE_BOOST_THREAD - PANDORA_REQUIRE_BOOST_REGEX - PANDORA_REQUIRE_BOOST_DATE_TIME - PANDORA_REQUIRE_BOOST_FILESYSTEM - PANDORA_REQUIRE_BOOST_IOSTREAMS - -]) diff --git a/m4/pandora_have_libreadline.m4 b/m4/pandora_have_libreadline.m4 deleted file mode 100644 index b49e97dd..00000000 --- a/m4/pandora_have_libreadline.m4 +++ /dev/null @@ -1,242 +0,0 @@ -# -# SYNOPSIS -# -# PANDORA_HAVE_LIBREADLINE -# -# DESCRIPTION -# -# Searches for a readline compatible library. If found, defines -# `HAVE_LIBREADLINE'. If the found library has the `add_history' -# function, sets also `HAVE_READLINE_HISTORY'. Also checks for the -# locations of the necessary include files and sets `HAVE_READLINE_H' -# or `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or -# 'HAVE_HISTORY_H' if the corresponding include files exists. -# -# The libraries that may be readline compatible are `libedit', -# `libeditline' and `libreadline'. Sometimes we need to link a -# termcap library for readline to work, this macro tests these cases -# too by trying to link with `libtermcap', `libcurses' or -# `libncurses' before giving up. -# -# Here is an example of how to use the information provided by this -# macro to perform the necessary includes or declarations in a C -# file: -# -# #ifdef HAVE_LIBREADLINE -# # if defined(HAVE_READLINE_READLINE_H) -# # include -# # elif defined(HAVE_READLINE_H) -# # include -# # else /* !defined(HAVE_READLINE_H) */ -# extern char *readline (); -# # endif /* !defined(HAVE_READLINE_H) */ -# char *cmdline = NULL; -# #else /* !defined(HAVE_READLINE_READLINE_H) */ -# /* no readline */ -# #endif /* HAVE_LIBREADLINE */ -# -# #ifdef HAVE_READLINE_HISTORY -# # if defined(HAVE_READLINE_HISTORY_H) -# # include -# # elif defined(HAVE_HISTORY_H) -# # include -# # else /* !defined(HAVE_HISTORY_H) */ -# extern void add_history (); -# extern int write_history (); -# extern int read_history (); -# # endif /* defined(HAVE_READLINE_HISTORY_H) */ -# /* no history */ -# #endif /* HAVE_READLINE_HISTORY */ -# -# LAST MODIFICATION -# -# 2009-11-17 -# -# Based on VL_LIB_READLINE from Ville Laurikari -# -# COPYLEFT -# -# Copyright (C) 2009 Monty Taylor -# Copyright (C) 2002 Ville Laurikari -# -# 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. - -AC_DEFUN([PANDORA_CHECK_TIOCGWINSZ],[ - AC_CACHE_CHECK([for TIOCGWINSZ in sys/ioctl.h], - [pandora_cv_tiocgwinsz_in_ioctl],[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include -#include - ]],[[ -int x= TIOCGWINSZ; - ]]) - ],[ - pandora_cv_tiocgwinsz_in_ioctl=yes - ],[ - pandora_cv_tiocgwinsz_in_ioctl=no - ]) - ]) - AS_IF([test "$pandora_cv_tiocgwinsz_in_ioctl" = "yes"],[ - AC_DEFINE([GWINSZ_IN_SYS_IOCTL], [1], - [READLINE: your system defines TIOCGWINSZ in sys/ioctl.h.]) - ]) -]) - -AC_DEFUN([PANDORA_CHECK_RL_COMPENTRY], [ - AC_CACHE_CHECK([defined rl_compentry_func_t], [pandora_cv_rl_compentry],[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include "stdio.h" -#include "readline/readline.h" - ]],[[ -rl_compentry_func_t *func2= (rl_compentry_func_t*)0; - ]]) - ],[ - pandora_cv_rl_compentry=yes - ],[ - pandora_cv_rl_compentry=no - ]) - ]) - AS_IF([test "$pandora_cv_rl_compentry" = "yes"],[ - AC_DEFINE([HAVE_RL_COMPENTRY], [1], - [Does system provide rl_compentry_func_t]) - ]) - - save_CXXFLAGS="${CXXFLAGS}" - CXXFLAGS="${AM_CXXFLAGS} ${CXXFLAGS}" - AC_LANG_PUSH(C++) - AC_CACHE_CHECK([rl_compentry_func_t works], [pandora_cv_rl_compentry_works],[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include "stdio.h" -#include "readline/readline.h" - ]],[[ -rl_completion_entry_function= (rl_compentry_func_t*)NULL; - ]]) - ],[ - pandora_cv_rl_compentry_works=yes - ],[ - pandora_cv_rl_compentry_works=no - ]) - ]) - AS_IF([test "$pandora_cv_rl_compentry_works" = "yes"],[ - AC_DEFINE([HAVE_WORKING_RL_COMPENTRY], [1], - [Does system provide an rl_compentry_func_t that is usable]) - ]) - CXXFLAGS="${save_CXXFLAGS}" - AC_LANG_POP() -]) - - -AC_DEFUN([PANDORA_CHECK_RL_COMPLETION_FUNC], [ - AC_CACHE_CHECK([defined rl_completion_func_t], [pandora_cv_rl_completion],[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include "stdio.h" -#include "readline/readline.h" - ]],[[ -rl_completion_func_t *func1= (rl_completion_func_t*)0; - ]]) - ],[ - pandora_cv_rl_completion=yes - ],[ - pandora_cv_rl_completion=no - ]) - ]) - AS_IF([test "$pandora_cv_rl_completion" = "yes"],[ - AC_DEFINE([HAVE_RL_COMPLETION], [1], - [Does system provide rl_completion_func_t]) - ]) -]) - -AC_DEFUN([_PANDORA_SEARCH_LIBREADLINE], [ - - save_LIBS="${LIBS}" - LIBS="" - - AC_CACHE_CHECK([for a readline compatible library], - ac_cv_libreadline, [ - ORIG_LIBS="$LIBS" - for readline_lib in readline edit editline; do - for termcap_lib in "" termcap curses ncurses; do - if test -z "$termcap_lib"; then - TRY_LIB="-l$readline_lib" - else - TRY_LIB="-l$readline_lib -l$termcap_lib" - fi - LIBS="$ORIG_LIBS $TRY_LIB" - AC_TRY_LINK_FUNC(readline, ac_cv_libreadline="$TRY_LIB") - if test -n "$ac_cv_libreadline"; then - break - fi - done - if test -n "$ac_cv_libreadline"; then - break - fi - done - if test -z "$ac_cv_libreadline"; then - ac_cv_libreadline="no" - LIBS="$ORIG_LIBS" - fi - ]) - - if test "$ac_cv_libreadline" != "no"; then - AC_DEFINE(HAVE_LIBREADLINE, 1, - [Define if you have a readline compatible library]) - AC_CHECK_HEADERS(readline.h readline/readline.h) - AC_CACHE_CHECK([whether readline supports history], - ac_cv_libreadline_history, [ - ac_cv_libreadline_history="no" - AC_TRY_LINK_FUNC(add_history, ac_cv_libreadline_history="yes") - ]) - if test "$ac_cv_libreadline_history" = "yes"; then - AC_DEFINE(HAVE_READLINE_HISTORY, 1, - [Define if your readline library has \`add_history']) - AC_CHECK_HEADERS(history.h readline/history.h) - fi - fi - PANDORA_CHECK_RL_COMPENTRY - PANDORA_CHECK_RL_COMPLETION_FUNC - PANDORA_CHECK_TIOCGWINSZ - - - READLINE_LIBS="${LIBS}" - LIBS="${save_LIBS}" - AC_SUBST(READLINE_LIBS) - - AM_CONDITIONAL(HAVE_LIBREADLINE, [test "x${ac_cv_libreadline}" = "xyes"]) -]) - -AC_DEFUN([_PANDORA_HAVE_LIBREADLINE],[ - - AC_ARG_ENABLE([libreadline], - [AS_HELP_STRING([--disable-libreadline], - [Build with libreadline support @<:@default=on@:>@])], - [ac_enable_libreadline="$enableval"], - [ac_enable_libreadline="yes"]) - - _PANDORA_SEARCH_LIBREADLINE -]) - - -AC_DEFUN([PANDORA_HAVE_LIBREADLINE],[ - AC_REQUIRE([_PANDORA_HAVE_LIBREADLINE]) -]) - -AC_DEFUN([_PANDORA_REQUIRE_LIBREADLINE],[ - ac_enable_libreadline="yes" - _PANDORA_SEARCH_LIBREADLINE - - AS_IF([test "x$ac_cv_libreadline" = "xno"], - AC_MSG_ERROR([libreadline is required for ${PACKAGE}. On Debian this can be found in libreadline5-dev. On RedHat this can be found in readline-devel.])) - -]) - -AC_DEFUN([PANDORA_REQUIRE_LIBREADLINE],[ - AC_REQUIRE([_PANDORA_REQUIRE_LIBREADLINE]) -]) - - diff --git a/tests/mem_functions.c b/tests/mem_functions.c index e3f6426a..bd01908e 100644 --- a/tests/mem_functions.c +++ b/tests/mem_functions.c @@ -5752,7 +5752,7 @@ static test_return_t regression_bug_583031(memcached_st *unused) (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc); - test_true_got(rc == MEMCACHED_TIMEOUT || rc == MEMCACHED_ERRNO, memcached_strerror(memc, rc)); + test_true_got(rc == MEMCACHED_TIMEOUT || rc == MEMCACHED_ERRNO || rc == MEMCACHED_FAILURE, memcached_strerror(memc, rc)); memcached_free(memc);