include util/include.am
include win32/include.am
+include m4/include.am
+
if HAVE_LIBEVENT
include memcached/include.am
libtest_libtest_la_DEPENDENCIES+= memcached/memcached
@find ./ | $(GREP) \.gcda | xargs rm -f
@find ./ | $(GREP) \.gcno | xargs rm -f
@find ./ | $(GREP) \.gz | xargs rm -f
- @find ./ | $(GREP) \.orig | xargs rm -f
+ @find ./ | $(GREP) \.moved | xargs rm -r -f
+ @find ./ | $(GREP) \\.orig | xargs rm -f
@find ./ | $(GREP) \.rej | xargs rm -f
- @find ./ | $(GREP) \.rpm | xargs rm -f
+ @rm -f *\.rpm
@find ./ | $(GREP) \.THIS | xargs rm -f
@find ./ | $(GREP) \.OTHER | xargs rm -f
@find ./ | $(GREP) \.BASE | xargs rm -f
#!/bin/sh
-# Copyright (C) 2011 Brian Aker
+# Copyright (C) 2011 Brian Aker, brian@tangent.org
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
}
-AUTORECONF_FLAGS=" --install --force --verbose -Wall"
+AUTORECONF_FLAGS=" --install --verbose -Wall"
if test -f config/pre_hook.sh
then
m4_include([m4/memcached_sasl.m4])
m4_include([m4/gearmand.m4])
m4_include([m4/libgearman.m4])
-m4_include([memcached/version.m4])
AM_CONDITIONAL(BUILDING_LIBMEMCACHED, true)
AM_CONDITIONAL(HAVE_LIBMEMCACHED, false)
AC_SEARCH_LIBS(getopt_long, gnugetopt)
AC_SEARCH_LIBS(gethostbyname, nsl)
-case "$target_os" in
- *linux*)
- AS_IF([test "x$GCC" = "xyes"],
- [
- LDFLAGS="$LDFLAGS -z relro -z now"
- ])
- ;;
- esac
-
dnl Specialty checks
-AX_PTHREAD
AX_CXX_CINTTYPES
CONFIG_EXTRA
DETECT_BYTEORDER
ENABLE_DEPRECATED
AC_CHECK_FUNCS([alarm])
+AC_CHECK_FUNCS([clock_gettime])
AC_CHECK_FUNCS([dup2])
AC_CHECK_FUNCS([getline])
AC_CHECK_FUNCS([gettimeofday])
AX_CHECK_SOCK_CLOEXEC([AC_DEFINE([HAVE_SOCK_CLOEXEC], [1], [Check for SOCK_CLOEXEC.])],
[AC_DEFINE([HAVE_SOCK_CLOEXEC], [0], [Check for SOCK_CLOEXEC.])])
+AX_HARDEN_COMPILER_FLAGS
+AX_PTHREAD
+
AC_CONFIG_FILES([
Makefile
docs/conf.py
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
-extensions = ['sphinxcontrib.googleanalytics']
+#extensions = ['sphinxcontrib.googleanalytics']
# Google
-googleanalytics_id = 'UA-15307604-2'
-googleanalytics_enabled = 'True'
+#googleanalytics_id = 'UA-15307604-2'
+#googleanalytics_enabled = 'True'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# General information about the project.
project = u'libmemcached'
-copyright = u'2011, Brian Aker DataDifferential, http://datadifferential.com/'
+copyright = u'2011-2012, Brian Aker DataDifferential, http://datadifferential.com/'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
-.TH "HASHKIT_CLONE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_CLONE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_clone \- libhashkit Documentation
.
-.TH "HASHKIT_CRC32" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_CRC32" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_crc32 \- libhashkit Documentation
.
-.TH "HASHKIT_CREATE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_CREATE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_create \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1_32" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FNV1_32" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_fnv1_32 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1_64" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FNV1_64" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_fnv1_64 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1A_32" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FNV1A_32" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_fnv1a_32 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1A_64" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FNV1A_64" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_fnv1a_64 \- libhashkit Documentation
.
-.TH "HASHKIT_FREE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FREE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_free \- libhashkit Documentation
.
-.TH "HASHKIT_FUNCTIONS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_FUNCTIONS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_functions \- libhashkit Documentation
.
-.TH "HASHKIT_HSIEH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_HSIEH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_hsieh \- libhashkit Documentation
.
-.TH "HASHKIT_IS_ALLOCATED" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_IS_ALLOCATED" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_is_allocated \- libhashkit Documentation
.
-.TH "HASHKIT_JENKINS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_JENKINS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_jenkins \- libhashkit Documentation
.
-.TH "HASHKIT_MD5" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_MD5" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_md5 \- libhashkit Documentation
.
-.TH "HASHKIT_MURMUR" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_MURMUR" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_murmur \- libhashkit Documentation
.
-.TH "HASHKIT_VALUE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "HASHKIT_VALUE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
hashkit_value \- libhashkit Documentation
.
-.TH "LIBHASHKIT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBHASHKIT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libhashkit \- libhashkit Documentation
.
-.TH "LIBMEMCACHED" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBMEMCACHED" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libmemcached \- Introducing the C Client Library for memcached
.
-.TH "LIBMEMCACHED_CHECK_CONFIGURATION" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBMEMCACHED_CHECK_CONFIGURATION" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libmemcached_check_configuration \- libmemcached Documentation
.
-.TH "LIBMEMCACHED_CONFIGURATION" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBMEMCACHED_CONFIGURATION" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libmemcached_configuration \- libmemcached Documentation
.
-.TH "LIBMEMCACHED_EXAMPLES" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBMEMCACHED_EXAMPLES" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libmemcached_examples \- libmemcached Documentation
.
-.TH "LIBMEMCACHEDUTIL" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "LIBMEMCACHEDUTIL" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
libmemcachedutil \- libmemcached Documentation
.
-.TH "MEMASLAP" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMASLAP" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memaslap \- libmemcached Documentation
.
-.TH "MEMCACHED" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached \- libmemcached Documentation
.
-.TH "MEMCACHED_ADD" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_ADD" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_add \- Storing and Replacing Data
.
-.TH "MEMCACHED_ADD_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_ADD_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_add_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_ANALYZE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_ANALYZE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_analyze \- libmemcached Documentation
.
-.TH "MEMCACHED_APPEND" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_APPEND" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_append \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_APPEND_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_APPEND_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_append_by_key \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_AUTO" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_AUTO" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_auto \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_BEHAVIOR" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_behavior \- libmemcached Documentation
.
-.TH "MEMCACHED_BEHAVIOR_GET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR_GET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_behavior_get \- libmemcached Documentation
.
-.TH "MEMCACHED_BEHAVIOR_SET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR_SET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_behavior_set \- libmemcached Documentation
.
-.TH "MEMCACHED_CALLBACK" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CALLBACK" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_callback \- libmemcached Documentation
.
-.TH "MEMCACHED_CALLBACK_GET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CALLBACK_GET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_callback_get \- libmemcached Documentation
.
-.TH "MEMCACHED_CALLBACK_SET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CALLBACK_SET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_callback_set \- libmemcached Documentation
.
-.TH "MEMCACHED_CAS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CAS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_cas \- Working with data on the server in an atomic fashion
.
-.TH "MEMCACHED_CAS_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CAS_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_cas_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_CLONE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CLONE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_clone \- libmemcached Documentation
.
-.TH "MEMCACHED_CREATE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_CREATE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_create \- libmemcached Documentation
.
-.TH "MEMCACHED_DECREMENT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DECREMENT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_decrement \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_DECREMENT_WITH_INITIAL" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DECREMENT_WITH_INITIAL" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_decrement_with_initial \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_DELETE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DELETE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_delete \- libmemcached Documentation
.
-.TH "MEMCACHED_DELETE_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DELETE_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_delete_by_key \- libmemcached Documentation
.
-.TH "MEMCACHED_DESTROY_SASL_AUTH_DATA" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DESTROY_SASL_AUTH_DATA" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_destroy_sasl_auth_data \- libmemcached Documentation
.
-.TH "MEMCACHED_DUMP" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_DUMP" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_dump \- libmemcached Documentation
.
-.TH "MEMCACHED_EXIST" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_EXIST" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_exist \- libmemcached Documentation
.
-.TH "MEMCACHED_EXIST_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_EXIST_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_exist_by_key \- libmemcached Documentation
.
-.TH "MEMCACHED_FETCH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FETCH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_fetch \- Retrieving data from the server
.
-.TH "MEMCACHED_FETCH_EXECUTE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FETCH_EXECUTE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_fetch_execute \- Retrieving data from the server
.
-.TH "MEMCACHED_FETCH_RESULT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FETCH_RESULT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_fetch_result \- Retrieving data from the server
.
-.TH "MEMCACHED_FLUSH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FLUSH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_flush \- libmemcached Documentation
.
-.TH "MEMCACHED_FLUSH_BUFFERS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FLUSH_BUFFERS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_flush_buffers \- libmemcached Documentation
.
-.TH "MEMCACHED_FREE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_FREE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_free \- libmemcached Documentation
.
-.TH "MEMCACHED_GENERATE_HASH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GENERATE_HASH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_generate_hash \- Generating hash values directly
.
-.TH "MEMCACHED_GENERATE_HASH_VALUE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GENERATE_HASH_VALUE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_generate_hash_value \- Generating hash values directly
.
-.TH "MEMCACHED_GET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_get \- Retrieving data from the server
.
-.TH "MEMCACHED_GET_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GET_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_get_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_GET_MEMORY_ALLOCATORS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GET_MEMORY_ALLOCATORS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_get_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_GET_SASL_CALLBACKS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GET_SASL_CALLBACKS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_get_sasl_callbacks \- libmemcached Documentation
.
-.TH "MEMCACHED_GET_USER_DATA" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_GET_USER_DATA" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_get_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_INCREMENT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_INCREMENT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_increment \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_INCREMENT_WITH_INITIAL" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_INCREMENT_WITH_INITIAL" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_increment_with_initial \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_LAST_ERROR_MESSAGE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_LAST_ERROR_MESSAGE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_last_error_message \- libmemcached Documentation
.
-.TH "MEMCACHED_LIB_VERSION" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_LIB_VERSION" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_lib_version \- libmemcached Documentation
.
-.TH "MEMCACHED_MEMORY_ALLOCATORS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_MEMORY_ALLOCATORS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_MGET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_MGET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_mget \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_MGET_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_mget_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_EXECUTE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_MGET_EXECUTE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_mget_execute \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_EXECUTE_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_MGET_EXECUTE_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_mget_execute_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_POOL" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_BEHAVIOR_GET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_BEHAVIOR_GET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_behavior_get \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_BEHAVIOR_SET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_BEHAVIOR_SET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_behavior_set \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_CREATE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_CREATE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_create \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_DESTROY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_DESTROY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_destroy \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_FETCH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_FETCH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_fetch \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_POP" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_POP" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_pop \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_PUSH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_PUSH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_push \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_RELEASE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_RELEASE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_release \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_ST" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_POOL_ST" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_pool_st \- libmemcached Documentation
.
-.TH "MEMCACHED_PREPEND" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_PREPEND" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_prepend \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_PREPEND_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_PREPEND_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_prepend_by_key \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_QUIT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_QUIT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_quit \- libmemcached Documentation
.
-.TH "MEMCACHED_REPLACE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_REPLACE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_replace \- Storing and Replacing Data
.
-.TH "MEMCACHED_REPLACE_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_REPLACE_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_replace_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_RESULT_CAS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_CAS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_cas \- Working with result sets
.
-.TH "MEMCACHED_RESULT_CREATE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_CREATE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_create \- Working with result sets
.
-.TH "MEMCACHED_RESULT_FLAGS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_FLAGS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_flags \- Working with result sets
.
-.TH "MEMCACHED_RESULT_FREE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_FREE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_free \- Working with result sets
.
-.TH "MEMCACHED_RESULT_KEY_LENGTH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_KEY_LENGTH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_key_length \- Working with result sets
.
-.TH "MEMCACHED_RESULT_KEY_VALUE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_KEY_VALUE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_key_value \- Working with result sets
.
-.TH "MEMCACHED_RESULT_LENGTH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_LENGTH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_length \- Working with result sets
.
-.TH "MEMCACHED_RESULT_ST" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_ST" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_st \- Working with result sets
.
-.TH "MEMCACHED_RESULT_VALUE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RESULT_VALUE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_result_value \- Working with result sets
.
-.TH "MEMCACHED_RETURN_T" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_RETURN_T" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_return_t \- Return type values
.
-.TH "MEMCACHED_SASL" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SASL" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_sasl \- libmemcached Documentation
.
-.TH "MEMCACHED_SASL_SET_AUTH_DATA" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SASL_SET_AUTH_DATA" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_sasl_set_auth_data \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ADD" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_ADD" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_add \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ADD_UNIX_SOCKET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_ADD_UNIX_SOCKET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_add_unix_socket \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_COUNT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_COUNT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_count \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_CURSOR" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_CURSOR" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_cursor \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_list \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_APPEND" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_APPEND" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_list_append \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_COUNT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_COUNT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_list_count \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_FREE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_FREE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_list_free \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_PUSH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_PUSH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_push \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ST" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVER_ST" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_server_st \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVERS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_servers \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS_PARSE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVERS_PARSE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_servers_parse \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS_RESET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SERVERS_RESET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_servers_reset \- libmemcached Documentation
.
-.TH "MEMCACHED_SET" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set \- Storing and Replacing Data
.
-.TH "MEMCACHED_SET_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_SET_ENCODING_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_ENCODING_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_encoding_key \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_MEMORY_ALLOCATORS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_MEMORY_ALLOCATORS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_MEMORY_ALLOCATORS_CONTEXT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_MEMORY_ALLOCATORS_CONTEXT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_memory_allocators_context \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_SASL_CALLBACKS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_SASL_CALLBACKS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_sasl_callbacks \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_USER_DATA" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_SET_USER_DATA" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_set_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STAT" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stat \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_EXECUTE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STAT_EXECUTE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stat_execute \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_GET_KEYS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STAT_GET_KEYS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stat_get_keys \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_GET_VALUE" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STAT_GET_VALUE" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stat_get_value \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_SERVERNAME" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STAT_SERVERNAME" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stat_servername \- libmemcached Documentation
.
-.TH "MEMCACHED_STATS" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STATS" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_stats \- libmemcached Documentation
.
-.TH "MEMCACHED_STRERROR" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_STRERROR" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_strerror \- libmemcached Documentation
.
-.TH "MEMCACHED_TOUCH" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_TOUCH" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_touch \- libmemcached Documentation
.
-.TH "MEMCACHED_TOUCH_BY_KEY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_TOUCH_BY_KEY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_touch_by_key \- libmemcached Documentation
.
-.TH "MEMCACHED_USER_DATA" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_USER_DATA" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_VERBOSITY" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_VERBOSITY" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_verbosity \- libmemcached Documentation
.
-.TH "MEMCACHED_VERSION" "3" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCACHED_VERSION" "3" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcached_version \- libmemcached Documentation
.
-.TH "MEMCAPABLE" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCAPABLE" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcapable \- libmemcached Documentation
.
-.TH "MEMCAT" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCAT" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcat \- libmemcached Documentation
.
-.TH "MEMCP" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMCP" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memcp \- libmemcached Documentation
.
-.TH "MEMDUMP" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMDUMP" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memdump \- libmemcached Documentation
.
-.TH "MEMERROR" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMERROR" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memerror \- libmemcached Documentation
.
-.TH "MEMEXIST" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMEXIST" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memexist \- libmemcached Documentation
.
-.TH "MEMFLUSH" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMFLUSH" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memflush \- libmemcached Documentation
.
-.TH "MEMPARSE" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMPARSE" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memparse \- libmemcached Documentation
.
-.TH "MEMPING" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMPING" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memping \- libmemcached Documentation
.
-.TH "MEMRM" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMRM" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memrm \- libmemcached Documentation
.
-.TH "MEMSLAP" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMSLAP" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memslap \- libmemcached Documentation
.
-.TH "MEMSTAT" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMSTAT" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memstat \- libmemcached Documentation
.
-.TH "MEMTOUCH" "1" "July 31, 2012" "1.0.10" "libmemcached"
+.TH "MEMTOUCH" "1" "August 02, 2012" "1.0.10" "libmemcached"
.SH NAME
memtouch \- libmemcached Documentation
.
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->create(world_create);
world->destroy(world_destroy);
bool is_purging:1;
bool is_processing_input:1;
bool is_time_for_rebuild:1;
- bool not_used:1;
+ bool is_parsing:1;
} state;
struct {
}
#ifdef HAVE_SNDTIMEO
- if (server->root->snd_timeout)
+ if (server->root->snd_timeout > 0)
{
struct timeval waittime;
- waittime.tv_sec= 0;
- waittime.tv_usec= server->root->snd_timeout;
+ waittime.tv_sec= server->root->snd_timeout / 1000000;
+ waittime.tv_usec= server->root->snd_timeout % 1000000;
int error= setsockopt(server->fd, SOL_SOCKET, SO_SNDTIMEO,
- &waittime, (socklen_t)sizeof(struct timeval));
+ &waittime, (socklen_t)sizeof(struct timeval));
+ (void)error;
assert(error == 0);
}
#endif
#ifdef HAVE_RCVTIMEO
- if (server->root->rcv_timeout)
+ if (server->root->rcv_timeout > 0)
{
struct timeval waittime;
- waittime.tv_sec= 0;
- waittime.tv_usec= server->root->rcv_timeout;
+ waittime.tv_sec= server->root->rcv_timeout / 1000000;
+ waittime.tv_usec= server->root->rcv_timeout % 1000000;
int error= setsockopt(server->fd, SOL_SOCKET, SO_RCVTIMEO,
&waittime, (socklen_t)sizeof(struct timeval));
+ (void)(error);
assert(error == 0);
}
#endif
int set= 1;
int error= setsockopt(server->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
+ assert(error == 0);
+
// This is not considered a fatal error
if (error == -1)
{
- WATCHPOINT_ERRNO(get_socket_errno());
+#if 0
perror("setsockopt(SO_NOSIGPIPE)");
+#endif
}
}
#endif
linger.l_linger= 0; /* By default on close() just drop the socket */
int error= setsockopt(server->fd, SOL_SOCKET, SO_LINGER,
&linger, (socklen_t)sizeof(struct linger));
+ (void)(error);
assert(error == 0);
}
int error= setsockopt(server->fd, IPPROTO_TCP, TCP_NODELAY,
&flag, (socklen_t)sizeof(int));
+ (void)(error);
assert(error == 0);
}
int error= setsockopt(server->fd, SOL_SOCKET, SO_KEEPALIVE,
&flag, (socklen_t)sizeof(int));
+ (void)(error);
assert(error == 0);
}
{
int error= setsockopt(server->fd, IPPROTO_TCP, TCP_KEEPIDLE,
&server->root->tcp_keepidle, (socklen_t)sizeof(int));
+ (void)(error);
assert(error == 0);
}
#endif
{
int error= setsockopt(server->fd, SOL_SOCKET, SO_SNDBUF,
&server->root->send_size, (socklen_t)sizeof(int));
+ (void)(error);
assert(error == 0);
}
{
int error= setsockopt(server->fd, SOL_SOCKET, SO_RCVBUF,
&server->root->recv_size, (socklen_t)sizeof(int));
+ (void)(error);
assert(error == 0);
}
memcached_return_t memcached_connect_try(org::libmemcached::Instance* server)
{
+ if (server and server->root and server->root->state.is_parsing)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+
return _memcached_connect(server, false);
}
memc= memc_arg;
init_scanner();
rc= MEMCACHED_SUCCESS;
+
+ memc->state.is_parsing= true;
}
bool end()
~Context()
{
destroy_scanner();
+ memc->state.is_parsing= false;
}
yytokentype previous_token;
self->state.is_purging= false;
self->state.is_processing_input= false;
self->state.is_time_for_rebuild= false;
+ self->state.is_parsing= false;
self->flags.auto_eject_hosts= false;
self->flags.binary_protocol= false;
#include <sys/types.h>
#include <unistd.h>
+#include <algorithm>
+
#ifndef __USE_GNU
static char **environ= NULL;
#endif
namespace {
- std::string print_argv(char * * & built_argv, const size_t& argc)
+ std::string print_argv(libtest::vchar_ptr_t& built_argv)
{
std::stringstream arg_buffer;
- for (size_t x= 0; x < argc; ++x)
+ for (vchar_ptr_t::iterator iter= built_argv.begin();
+ iter == built_argv.end();
+ iter++)
{
- arg_buffer << built_argv[x] << " ";
+ arg_buffer << *iter << " ";
}
return arg_buffer.str();
}
+#if 0
std::string print_argv(char** argv)
{
std::stringstream arg_buffer;
return arg_buffer.str();
}
+#endif
static Application::error_t int_to_error_t(int arg)
{
stdin_fd(STDIN_FILENO),
stdout_fd(STDOUT_FILENO),
stderr_fd(STDERR_FILENO),
- built_argv(NULL),
_pid(-1)
{
if (_use_libtool)
}
else
{
+
if (_use_libtool)
{
- spawn_ret= posix_spawn(&_pid, built_argv[0], &file_actions, &spawnattr, built_argv, NULL);
+ spawn_ret= posix_spawn(&_pid, built_argv[0], &file_actions, &spawnattr, &built_argv[0], NULL);
}
else
{
- spawn_ret= posix_spawnp(&_pid, built_argv[0], &file_actions, &spawnattr, built_argv, NULL);
+ spawn_ret= posix_spawnp(&_pid, built_argv[0], &file_actions, &spawnattr, &built_argv[0], NULL);
}
}
return exit_code;
}
+Application::error_t Application::join()
+{
+ if (_pid == -1)
+ {
+ return Application::INVALID;
+ }
+
+ slurp();
+
+ error_t exit_code= FAILURE;
+ {
+ int status= 0;
+ pid_t waited_pid;
+ do {
+ waited_pid= waitpid(_pid, &status, 0);
+ } while (waited_pid == -1 and (errno == EINTR or errno == EAGAIN));
+
+ if (waited_pid == -1)
+ {
+ switch (errno)
+ {
+ case ECHILD:
+ exit_code= Application::SUCCESS;
+ break;
+
+ case EINTR:
+ break;
+
+ default:
+ Error << "Error occured while waitpid(" << strerror(errno) << ") on pid " << int(_pid);
+ break;
+ }
+ }
+ else if (waited_pid == 0)
+ {
+ exit_code= Application::SUCCESS;
+ }
+ else
+ {
+ if (waited_pid != _pid)
+ {
+ throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "Pid mismatch, %d != %d", int(waited_pid), int(_pid));
+ }
+
+ exit_code= int_to_error_t(exited_successfully(status));
+ }
+ }
+
+ slurp();
+
+#if 0
+ if (exit_code == Application::INVALID)
+ {
+ Error << print_argv(built_argv, _argc);
+ }
+#endif
+
+ return exit_code;
+}
+
void Application::add_long_option(const std::string& name, const std::string& option_value)
{
std::string arg(name);
data_was_read= true;
arg.reserve(read_length +1);
- for (size_t x= 0; x < read_length; ++x)
+ for (size_t x= 0; x < size_t(read_length); ++x)
{
arg.push_back(buffer[x]);
}
void Application::create_argv(const char *args[])
{
delete_argv();
- fatal_assert(_argc == 0);
-
- if (_use_libtool)
- {
- _argc+= 2; // +2 for libtool --mode=execute
- }
-
- _argc+= 1; // For the command
-
- /*
- valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --track-origin=yes --malloc-fill=A5 --free-fill=DE --log-file=
- */
- if (_use_valgrind)
- {
- _argc+= 8;
- }
- else if (_use_ptrcheck)
- {
- /*
- valgrind --error-exitcode=1 --tool=exp-ptrcheck --log-file=
- */
- _argc+= 4;
- }
- else if (_use_gdb) // gdb
- {
- _argc+= 1;
- }
-
- for (Options::const_iterator iter= _options.begin(); iter != _options.end(); ++iter)
- {
- _argc++;
- if ((*iter).second.empty() == false)
- {
- _argc++;
- }
- }
-
- if (args)
- {
- for (const char **ptr= args; *ptr; ++ptr)
- {
- _argc++;
- }
- }
-
- _argc+= 1; // for the NULL
-
- built_argv= new char * [_argc];
-
- size_t x= 0;
if (_use_libtool)
{
assert(libtool());
- built_argv[x++]= strdup(libtool());
- built_argv[x++]= strdup("--mode=execute");
+ built_argv.push_back(strdup(libtool()));
+ built_argv.push_back(strdup("--mode=execute"));
}
if (_use_valgrind)
/*
valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
*/
- built_argv[x++]= strdup("valgrind");
- built_argv[x++]= strdup("--error-exitcode=1");
- built_argv[x++]= strdup("--leak-check=yes");
- built_argv[x++]= strdup("--show-reachable=yes");
- built_argv[x++]= strdup("--track-fds=yes");
+ built_argv.push_back(strdup("valgrind"));
+ built_argv.push_back(strdup("--error-exitcode=1"));
+ built_argv.push_back(strdup("--leak-check=yes"));
+ built_argv.push_back(strdup("--show-reachable=yes"));
+ built_argv.push_back(strdup("--track-fds=yes"));
#if 0
built_argv[x++]= strdup("--track-origin=yes");
#endif
- built_argv[x++]= strdup("--malloc-fill=A5");
- built_argv[x++]= strdup("--free-fill=DE");
+ built_argv.push_back(strdup("--malloc-fill=A5"));
+ built_argv.push_back(strdup("--free-fill=DE"));
std::string log_file= create_tmpfile("valgrind");
char buffer[1024];
int length= snprintf(buffer, sizeof(buffer), "--log-file=%s", log_file.c_str());
- fatal_assert(length > 0 and length < sizeof(buffer));
- built_argv[x++]= strdup(buffer);
+ fatal_assert(length > 0 and size_t(length) < sizeof(buffer));
+ built_argv.push_back(strdup(buffer));
}
else if (_use_ptrcheck)
{
/*
valgrind --error-exitcode=1 --tool=exp-ptrcheck --log-file=
*/
- built_argv[x++]= strdup("valgrind");
- built_argv[x++]= strdup("--error-exitcode=1");
- built_argv[x++]= strdup("--tool=exp-ptrcheck");
- _argc+= 4;
+ built_argv.push_back(strdup("valgrind"));
+ built_argv.push_back(strdup("--error-exitcode=1"));
+ built_argv.push_back(strdup("--tool=exp-ptrcheck"));
std::string log_file= create_tmpfile("ptrcheck");
char buffer[1024];
int length= snprintf(buffer, sizeof(buffer), "--log-file=%s", log_file.c_str());
- fatal_assert(length > 0 and length < sizeof(buffer));
- built_argv[x++]= strdup(buffer);
+ fatal_assert(length > 0 and size_t(length) < sizeof(buffer));
+ built_argv.push_back(strdup(buffer));
}
else if (_use_gdb)
{
- built_argv[x++]= strdup("gdb");
+ built_argv.push_back(strdup("gdb"));
}
- built_argv[x++]= strdup(_exectuble_with_path.c_str());
+ built_argv.push_back(strdup(_exectuble_with_path.c_str()));
for (Options::const_iterator iter= _options.begin(); iter != _options.end(); ++iter)
{
- built_argv[x++]= strdup((*iter).first.c_str());
+ built_argv.push_back(strdup((*iter).first.c_str()));
if ((*iter).second.empty() == false)
{
- built_argv[x++]= strdup((*iter).second.c_str());
+ built_argv.push_back(strdup((*iter).second.c_str()));
}
}
{
for (const char **ptr= args; *ptr; ++ptr)
{
- built_argv[x++]= strdup(*ptr);
+ built_argv.push_back(strdup(*ptr));
}
}
- built_argv[x++]= NULL;
- fatal_assert(x == _argc);
+ built_argv.push_back(NULL);
}
std::string Application::print()
{
- return print_argv(built_argv, _argc);
+ return print_argv(built_argv);
}
std::string Application::arguments()
return arg_buffer.str();
}
-void Application::delete_argv()
+struct DeleteFromVector
{
- if (built_argv)
- {
- for (size_t x= 0; x < _argc; ++x)
+ template <class T>
+ void operator() ( T* ptr) const
{
- if (built_argv[x])
- {
- ::free(built_argv[x]);
- }
+ free(ptr);
}
- delete[] built_argv;
- built_argv= NULL;
- _argc= 0;
- }
+};
+
+void Application::delete_argv()
+{
+ std::for_each(built_argv.begin(), built_argv.end(), DeleteFromVector());
+
+ built_argv.clear();
+ _argc= 0;
}
return int(ret);
}
- return int(app.wait(false));
+ return int(app.join());
}
const char *gearmand_binary()
INVALID= 127
};
+ static const char* toString(error_t arg)
+ {
+ switch (arg)
+ {
+ case Application::SUCCESS:
+ return "EXIT_SUCCESS";
+
+ case Application::FAILURE:
+ return "EXIT_FAILURE";
+
+ case Application::INVALID:
+ return "127";
+
+ default:
+ break;
+ }
+
+ return "EXIT_UNKNOWN";
+ }
+
class Pipe {
public:
Pipe(int);
void add_long_option(const std::string& option_name, const std::string& option_value);
error_t run(const char *args[]= NULL);
error_t wait(bool nohang= true);
+ Application::error_t join();
libtest::vchar_t stdout_result() const
{
Pipe stdin_fd;
Pipe stdout_fd;
Pipe stderr_fd;
- char * * built_argv;
+ libtest::vchar_ptr_t built_argv;
pid_t _pid;
libtest::vchar_t _stdout_buffer;
libtest::vchar_t _stderr_buffer;
static inline std::ostream& operator<<(std::ostream& output, const enum Application::error_t &arg)
{
- switch (arg)
- {
- case Application::SUCCESS:
- output << "EXIT_SUCCESS";
- break;
-
- case Application::FAILURE:
- output << "EXIT_FAILURE";
- break;
-
- case Application::INVALID:
- output << "127";
- break;
-
- default:
- output << "EXIT_UNKNOWN";
- }
-
- return output;
+ return output << Application::toString(arg);
}
int exec_cmdline(const std::string& executable, const char *args[], bool use_libtool= false);
#include <libtest/common.h>
-static test_return_t runner_code(Framework* frame,
+static test_return_t runner_code(libtest::Framework* frame,
test_st* run,
libtest::Timer& _timer)
{ // Runner Code
_success(0),
_skipped(0),
_failed(0),
- _total(0)
+ _total(0),
+ _formatter(_name)
{
fatal_assert(arg);
}
test_return_t Collection::exec()
{
- Out << "Collection: " << _name;
-
if (test_success(_frame->runner()->pre(_pre, _frame->creators_ptr())))
{
for (test_st *run= _tests; run->name; run++)
{
+ formatter()->push_testcase(run->name);
if (_frame->match(run->name))
{
+ formatter()->skipped();
continue;
}
_total++;
{
Error << "frame->runner()->flush(creators_ptr)";
_skipped++;
+ formatter()->skipped();
continue;
}
}
- return_code= runner_code(_frame, run, _timer);
+ alarm(600);
+ try
+ {
+ return_code= runner_code(_frame, run, _timer);
+ }
+ catch (...)
+ {
+ alarm(0);
+ throw;
+ }
+ alarm(0);
}
- catch (libtest::fatal &e)
+ catch (libtest::exception &e)
{
stream::cerr(e.file(), e.line(), e.func()) << e.what();
_failed++;
+ formatter()->failed();
throw;
}
switch (return_code)
{
case TEST_SUCCESS:
- Out << "\tTesting "
- << run->name
- << "\t\t\t\t\t"
- << _timer
- << " [ " << test_strerror(return_code) << " ]";
_success++;
+ formatter()->success(_timer);
break;
case TEST_FAILURE:
_failed++;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+ formatter()->failed();
break;
case TEST_SKIPPED:
_skipped++;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+ formatter()->skipped();
break;
default:
#pragma once
+#include <libtest/formatter.hpp>
+
#include <libtest/timer.hpp>
-class Framework;
+namespace { class Framework; }
+
/**
A structure which describes a collection of test cases.
class Collection {
public:
- Collection(Framework*, collection_st*);
+ Collection(libtest::Framework*, collection_st*);
test_return_t exec();
const char* name()
{
- return _name;
+ return _name.c_str();
}
uint32_t success()
return _total;
}
+ libtest::Formatter* formatter()
+ {
+ return &_formatter;
+ }
+
private:
- const char *_name;
+ std::string _name;
test_callback_fn *_pre;
test_callback_fn *_post;
struct test_st *_tests;
- Framework* _frame;
+ libtest::Framework* _frame;
uint32_t _success;
uint32_t _skipped;
uint32_t _failed;
uint32_t _total;
libtest::Timer _timer;
+ libtest::Formatter _formatter;
};
} // namespace libtest
#include <libtest/killpid.h>
#include <libtest/signal.h>
#include <libtest/dns.hpp>
+#include <libtest/formatter.hpp>
namespace libtest {
bool ping_drizzled(const in_port_t _port)
{
+ (void)(_port);
#if defined(HAVE_LIBDRIZZLE) && HAVE_LIBDRIZZLE
{
drizzle_st *drizzle= drizzle_create(NULL);
return "drizzled";
};
- void log_file_option(Application& app, const std::string& arg)
+ void log_file_option(Application&, const std::string&)
{
}
namespace libtest {
-fatal::fatal(const char *file_arg, int line_arg, const char *func_arg, const char *format, ...) :
- std::runtime_error(func_arg),
- _line(line_arg),
- _file(file_arg),
- _func(func_arg)
+exception::exception(const char *file_, int line_, const char *func_) :
+ std::runtime_error(func_),
+ _file(file_),
+ _line(line_),
+ _func(func_)
+ {
+ }
+
+fatal::fatal(const char *file_, int line_, const char *func_, const char *format, ...) :
+ exception(file_, line_, func_)
{
va_list args;
va_start(args, format);
int last_error_length= vsnprintf(last_error, sizeof(last_error), format, args);
va_end(args);
- strncpy(_mesg, last_error, sizeof(_mesg));
-
snprintf(_error_message, sizeof(_error_message), "%.*s", last_error_length, last_error);
}
_counter++;
}
-disconnected::disconnected(const char *file_arg, int line_arg, const char *func_arg,
- const char *instance, const in_port_t port,
+disconnected::disconnected(const char *file_, int line_, const char *func_,
+ const std::string& instance, const in_port_t port,
const char *format, ...) :
- std::runtime_error(func_arg),
- _port(port),
- _line(line_arg),
- _file(file_arg),
- _func(func_arg)
+ exception(file_, line_, func_),
+ _port(port)
+{
+ va_list args;
+ va_start(args, format);
+ char last_error[BUFSIZ];
+ (void)vsnprintf(last_error, sizeof(last_error), format, args);
+ va_end(args);
+
+ snprintf(_error_message, sizeof(_error_message), "%s:%u %s", instance.c_str(), uint32_t(port), last_error);
+}
+
+start::start(const char *file_, int line_, const char *func_,
+ const std::string& instance, const in_port_t port,
+ const char *format, ...) :
+ exception(file_, line_, func_),
+ _port(port)
{
- strncpy(_instance, instance, sizeof(_instance));
va_list args;
va_start(args, format);
char last_error[BUFSIZ];
(void)vsnprintf(last_error, sizeof(last_error), format, args);
va_end(args);
- snprintf(_error_message, sizeof(_error_message), "%s", last_error);
+ snprintf(_error_message, sizeof(_error_message), "%s:%u %s", instance.c_str(), uint32_t(port), last_error);
}
} // namespace libtest
namespace libtest {
-class fatal : std::runtime_error
+class exception : public std::runtime_error
{
public:
- fatal(const char *file, int line, const char *func, const char *format, ...);
+ exception(const char *, int, const char *);
- const char* what() const throw()
+ int line() const
{
- return _error_message;
+ return _line;
}
- const char* mesg() const throw()
+ const char* file() const
{
- return _error_message;
+ return _file;
}
- // The following are just for unittesting the exception class
- static bool is_disabled();
- static void disable();
- static void enable();
- static uint32_t disabled_counter();
- static void increment_disabled_counter();
-
- int line()
+ const char* func() const
{
- return _line;
+ return _func;
}
- const char* file()
+ const char* mesg() const throw()
{
- return _file;
+ return _error_message;
}
- const char* func()
- {
- return _func;
- }
-private:
+protected:
char _error_message[BUFSIZ];
- char _mesg[BUFSIZ];
- int _line;
+
+private:
const char* _file;
+ int _line;
const char* _func;
};
-class disconnected : std::runtime_error
+class fatal : public exception
{
public:
- disconnected(const char *file, int line, const char *func, const char *instance, const in_port_t port, const char *format, ...);
+ fatal(const char *file, int line, const char *func, const char *format, ...);
const char* what() const throw()
{
static uint32_t disabled_counter();
static void increment_disabled_counter();
- int line()
- {
- return _line;
- }
+private:
+};
+
+class disconnected : public exception
+{
+public:
+ disconnected(const char *file, int line, const char *func, const std::string&, const in_port_t port, const char *format, ...);
- const char* file()
+ const char* what() const throw()
{
- return _file;
+ return _error_message;
}
- const char* func()
+ // The following are just for unittesting the exception class
+ static bool is_disabled();
+ static void disable();
+ static void enable();
+ static uint32_t disabled_counter();
+ static void increment_disabled_counter();
+
+private:
+ in_port_t _port;
+ char _instance[1024];
+};
+
+class start : public exception
+{
+public:
+ start(const char *file, int line, const char *func, const std::string&, const in_port_t port, const char *format, ...);
+
+ const char* what() const throw()
{
- return _func;
+ return _error_message;
}
+ // The following are just for unittesting the exception class
+ static bool is_disabled();
+ static void disable();
+ static void enable();
+ static uint32_t disabled_counter();
+ static void increment_disabled_counter();
+
private:
- char _error_message[BUFSIZ];
in_port_t _port;
char _instance[1024];
- int _line;
- const char* _file;
- const char* _func;
};
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Data Differential YATL (i.e. libtest) library
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ * 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 <config.h>
+
+#include <libtest/common.h>
+
+#include <iostream>
+#include <fstream>
+
+namespace libtest {
+
+class TestCase {
+public:
+ TestCase(const std::string& arg):
+ _name(arg),
+ _result(TEST_FAILURE)
+ {
+ }
+
+ const std::string& name() const
+ {
+ return _name;
+ }
+
+ test_return_t result() const
+ {
+ return _result;
+ }
+
+ void result(test_return_t arg)
+ {
+ _result= arg;
+ }
+
+ void result(test_return_t arg, const libtest::Timer& timer_)
+ {
+ _result= arg;
+ _timer= timer_;
+ }
+
+ const libtest::Timer& timer() const
+ {
+ return _timer;
+ }
+
+ void timer(libtest::Timer& arg)
+ {
+ _timer= arg;
+ }
+
+private:
+ std::string _name;
+ test_return_t _result;
+ libtest::Timer _timer;
+};
+
+Formatter::Formatter(const std::string& arg) :
+ _suite_name(arg)
+{
+}
+
+Formatter::~Formatter()
+{
+ for (TestCases::iterator iter= _testcases.begin(); iter != _testcases.end(); ++iter)
+ {
+ delete *iter;
+ }
+}
+
+TestCase* Formatter::current()
+{
+ return _testcases.back();
+}
+
+void Formatter::skipped()
+{
+ current()->result(TEST_SKIPPED);
+ Out << name() << "." << current()->name() << "\t\t\t\t\t" << "[ " << test_strerror(current()->result()) << " ]";
+
+ reset();
+}
+
+void Formatter::failed()
+{
+ assert(current());
+ current()->result(TEST_FAILURE);
+
+ Out << name() << "." << current()->name() << "\t\t\t\t\t" << "[ " << test_strerror(current()->result()) << " ]";
+
+ reset();
+}
+
+void Formatter::success(const libtest::Timer& timer_)
+{
+ assert(current());
+ current()->result(TEST_SUCCESS, timer_);
+
+ Out << name() << "."
+ << current()->name()
+ << "\t\t\t\t\t"
+ << current()->timer()
+ << " [ " << test_strerror(current()->result()) << " ]";
+
+ reset();
+}
+
+void Formatter::xml(libtest::Framework& framework_, std::ofstream& output)
+{
+ output << "<testsuites name=\"" << framework_.name() << "\">" << std::endl;
+ for (Suites::iterator framework_iter= framework_.suites().begin();
+ framework_iter != framework_.suites().end();
+ ++framework_iter)
+ {
+ output << "\t<testsuite name=\"" << (*framework_iter)->name() << "\" classname=\"\" package=\"\">" << std::endl;
+
+ for (TestCases::iterator case_iter= (*framework_iter)->formatter()->testcases().begin();
+ case_iter != (*framework_iter)->formatter()->testcases().end();
+ ++case_iter)
+ {
+ output << "\t\t<testcase name=\""
+ << (*case_iter)->name()
+ << "\" time=\""
+ << (*case_iter)->timer().elapsed_milliseconds()
+ << "\">"
+ << std::endl;
+
+ switch ((*case_iter)->result())
+ {
+ case TEST_SKIPPED:
+ output << "\t\t <skipped/>" << std::endl;
+ break;
+
+ case TEST_FAILURE:
+ output << "\t\t <failure message=\"\" type=\"\"/>"<< std::endl;
+ break;
+
+ case TEST_SUCCESS:
+ break;
+ }
+ output << "\t\t</testcase>" << std::endl;
+ }
+ output << "\t</testsuite>" << std::endl;
+ }
+ output << "</testsuites>" << std::endl;
+}
+
+void Formatter::push_testcase(const std::string& arg)
+{
+ assert(_suite_name.empty() == false);
+ TestCase* _current_testcase= new TestCase(arg);
+ _testcases.push_back(_current_testcase);
+}
+
+void Formatter::reset()
+{
+}
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Data Differential YATL (i.e. libtest) library
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ * 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.
+ *
+ */
+
+#pragma once
+
+#include <string>
+
+namespace libtest { class Framework; }
+
+
+namespace libtest {
+
+class TestCase;
+typedef std::vector<libtest::TestCase*> TestCases;
+
+class Formatter {
+public:
+ Formatter(const std::string& arg);
+
+ ~Formatter();
+
+ void skipped();
+
+ void failed();
+
+ void success(const libtest::Timer&);
+
+ void push_testcase(const std::string&);
+
+ const std::string& name() const
+ {
+ return _suite_name;
+ }
+
+ TestCases& testcases()
+ {
+ return _testcases;
+ }
+
+ static void xml(libtest::Framework&, std::ofstream&);
+
+private:
+ void reset();
+
+ TestCase* current();
+
+private:
+ std::string _suite_name;
+ TestCases _testcases;
+};
+
+} // namespace libtest
#include <fnmatch.h>
#include <iostream>
-using namespace libtest;
+namespace libtest {
Framework::Framework(libtest::SignalThread& signal,
+ const std::string& name_,
const std::string& only_run_arg,
const std::string& wildcard_arg) :
- _collections(NULL),
_total(0),
_success(0),
_skipped(0),
_creators_ptr(NULL),
_signal(signal),
_only_run(only_run_arg),
- _wildcard(wildcard_arg)
+ _wildcard(wildcard_arg),
+ _name(name_)
{
get_world(this);
+}
- for (collection_st *next= _collections; next and next->name; next++)
+void Framework::collections(collection_st* collections_)
+{
+ for (collection_st *next= collections_; next and next->name; next++)
{
_collection.push_back(new Collection(this, next));
}
_total++;
- try {
+ try
+ {
switch ((*iter)->exec())
{
case TEST_FAILURE:
catch (libtest::disconnected& e)
{
_failed++;
- Error << "Unhandled disconnection occurred:" << e.what();
+ stream::cerr(e.file(), e.line(), e.func()) << "Unhandled disconnection occurred: " << e.mesg();
throw;
}
catch (...)
_failed++;
throw;
}
-
- Outn();
}
+
+ void xml(const std::string& testsuites_name, std::ostream& output);
}
uint32_t Framework::sum_total()
return rc;
}
+
+} // namespace libtest
#include <vector>
+namespace { class Collection; }
+typedef std::vector<libtest::Collection*> Suites;
+
+namespace libtest {
+
class Framework {
public:
public:
test_return_t create();
+ const std::string& name() const
+ {
+ return _name;
+ }
+
void create(test_callback_create_fn* arg)
{
_create= arg;
_destroy= arg;
}
- void collections(collection_st* arg)
- {
- _collections= arg;
- }
+ void collections(collection_st* arg);
void set_on_error(test_callback_error_fn *arg)
{
libtest::Collection& collection();
- Framework(libtest::SignalThread&, const std::string&);
-
virtual ~Framework();
Framework(libtest::SignalThread&,
+ const std::string&,
const std::string&,
const std::string&);
return _failed;
}
+ Suites& suites()
+ {
+ return _collection;
+ }
+
private:
Framework& operator=(const Framework&);
- collection_st *_collections;
-
uint32_t _total;
uint32_t _success;
uint32_t _skipped;
bool _socket;
void *_creators_ptr;
unsigned long int _servers_to_run;
- std::vector<libtest::Collection*> _collection;
+ Suites _collection;
libtest::SignalThread& _signal;
std::string _only_run;
std::string _wildcard;
+ std::string _name;
};
+
+} // namespace libtest
if (out_of_ban_killed() == false)
{
- Error << hostname().c_str() << ":" << port() << " was " << gearman_strerror(rc) << " extended: " << gearman_client_error(client);
+ Error << hostname().c_str() << ":" << port() << " " << gearman_client_error(client);
}
}
else
/* How we make all of this work :) */
LIBTEST_API
- void get_world(Framework *world);
+ void get_world(libtest::Framework *world);
#ifdef __cplusplus
}
bool has_postgres_support(void)
{
- if (getenv("POSTGES_IS_RUNNING_AND_SETUP"))
+ char *getenv_ptr;
+ if (bool((getenv_ptr= getenv("POSTGES_IS_RUNNING_AND_SETUP"))))
{
+ (void)(getenv_ptr);
if (HAVE_LIBPQ)
{
return true;
{
if (HAVE_GEARMAND_BINARY)
{
+#if defined(HAVE_GEARMAND_BINARY) && HAVE_GEARMAND_BINARY
std::stringstream arg_buffer;
- if (getenv("PWD") and strcmp(MEMCACHED_BINARY, "gearmand/gearmand") == 0)
+ char *getenv_ptr;
+ if (bool((getenv_ptr= getenv("PWD"))) and
+ ((strcmp(GEARMAND_BINARY, "./gearmand/gearmand") == 0) or (strcmp(GEARMAND_BINARY, "gearmand/gearmand") == 0)))
{
- arg_buffer << getenv("PWD");
+ arg_buffer << getenv_ptr;
arg_buffer << "/";
}
arg_buffer << GEARMAND_BINARY;
{
return true;
}
+#endif
}
return false;
bool has_drizzled()
{
+#if defined(HAVE_DRIZZLED_BINARY) && HAVE_DRIZZLED_BINARY
if (HAVE_DRIZZLED_BINARY)
{
if (access(DRIZZLED_BINARY, X_OK) == 0)
return true;
}
}
+#endif
return false;
}
bool has_mysqld()
{
+#if defined(HAVE_MYSQLD_BUILD) && HAVE_MYSQLD_BUILD
if (HAVE_MYSQLD_BUILD)
{
if (access(MYSQLD_BINARY, X_OK) == 0)
return true;
}
}
+#endif
return false;
}
{
std::stringstream arg_buffer;
- if (getenv("PWD") and strcmp(MEMCACHED_BINARY, "memcached/memcached") == 0)
+
+ char *getenv_ptr;
+ if (bool((getenv_ptr= getenv("PWD"))) and strcmp(MEMCACHED_BINARY, "memcached/memcached") == 0)
{
- arg_buffer << getenv("PWD");
+ arg_buffer << getenv_ptr;
arg_buffer << "/";
}
arg_buffer << MEMCACHED_BINARY;
static void init(CURL *curl, const std::string& url)
{
+ (void)curl;
+ (void)url;
if (HAVE_LIBCURL)
{
#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
curl_easy_cleanup(curl);
- return retref == CURLE_OK;
+ return bool(retref == CURLE_OK);
#endif
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, _response);
curl_easy_cleanup(curl);
+
+ return bool(retref == CURLE_OK);
#endif
}
#pragma once
+#include <libtest/vchar.hpp>
+
namespace libtest {
namespace http {
VALGRIND_COMMAND= TESTS_ENVIRONMENT="valgrind" $(VALGRIND_EXEC_COMMAND)
HELGRIND_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=helgrind --read-var-info=yes --error-exitcode=1 --read-var-info=yes
DRD_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=drd
+MASSIF_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=massif
GDB_COMMAND= $(LIBTOOL_COMMAND) gdb -f -x libtest/run.gdb
PTRCHECK_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=exp-ptrcheck --error-exitcode=1
CLEANFILES+= tmp_chroot/var/log/*
CLEANFILES+= tmp_chroot/var/run/*
CLEANFILES+= tmp_chroot/var/tmp/*
+CLEANFILES+= tmp_chroot/*.xml
BUILT_SOURCES+= libtest/version.h
distclean-libtest-check:
-rm -rf tmp_chroot
+noinst_HEADERS+= libtest/formatter.hpp
noinst_HEADERS+= libtest/timer.hpp
noinst_HEADERS+= libtest/binaries.h
noinst_HEADERS+= libtest/cpu.hpp
libtest_libtest_la_SOURCES+= libtest/cpu.cc
libtest_libtest_la_SOURCES+= libtest/dream.cc
libtest_libtest_la_SOURCES+= libtest/fatal.cc
+libtest_libtest_la_SOURCES+= libtest/formatter.cc
libtest_libtest_la_SOURCES+= libtest/framework.cc
libtest_libtest_la_SOURCES+= libtest/has.cc
libtest_libtest_la_SOURCES+= libtest/drizzled.cc
@libtest/unittest
valgrind-unittest: libtest/unittest
- @$(VALGRIND_COMMAND) libtest/unittest TESTS_ENVIRONMENT="valgrind"
+ @$(VALGRIND_COMMAND) libtest/unittest
gdb-unittest: libtest/unittest
@$(GDB_COMMAND) libtest/unittest
#include <ctime>
#include <fnmatch.h>
#include <iostream>
+#include <fstream>
#include <memory>
#include <sys/stat.h>
#include <sys/time.h>
using namespace libtest;
-static void stats_print(Framework *frame)
+static void stats_print(libtest::Framework *frame)
{
if (frame->failed() == 0 and frame->success() == 0)
{
bool opt_quiet= false;
std::string collection_to_run;
std::string wildcard;
+ std::string binary_name;
+
+ const char *just_filename= rindex(argv[0], '/');
+ if (just_filename)
+ {
+ just_filename++;
+ }
+ else
+ {
+ just_filename= argv[0];
+ }
+
+ if (just_filename[0] == 'l' and just_filename[1] == 't' and just_filename[2] == '-')
+ {
+ just_filename+= 3;
+ }
+ binary_name.append(just_filename);
/*
Valgrind does not currently work reliably, or sometimes at all, on OSX
is_massive(opt_massive);
}
- char buffer[1024];
+ char tmp_directory[1024];
if (getenv("LIBTEST_TMP"))
{
- snprintf(buffer, sizeof(buffer), "%s", getenv("LIBTEST_TMP"));
+ snprintf(tmp_directory, sizeof(tmp_directory), "%s", getenv("LIBTEST_TMP"));
}
else
{
- snprintf(buffer, sizeof(buffer), "%s", LIBTEST_TEMP);
+ snprintf(tmp_directory, sizeof(tmp_directory), "%s", LIBTEST_TEMP);
}
- if (chdir(buffer) == -1)
+ if (chdir(tmp_directory) == -1)
{
char getcwd_buffer[1024];
char *dir= getcwd(getcwd_buffer, sizeof(getcwd_buffer));
- Error << "Unable to chdir() from " << dir << " to " << buffer << " errno:" << strerror(errno);
+ Error << "Unable to chdir() from " << dir << " to " << tmp_directory << " errno:" << strerror(errno);
return EXIT_FAILURE;
}
return EXIT_FAILURE;
}
- std::auto_ptr<Framework> frame(new Framework(signal, collection_to_run, wildcard));
+ std::auto_ptr<libtest::Framework> frame(new libtest::Framework(signal, binary_name, collection_to_run, wildcard));
// Run create(), bail on error.
{
}
else if (frame->success() and (frame->failed() == 0))
{
+ Out;
Out << "All tests completed successfully.";
}
stats_print(frame.get());
+ std::ofstream xml_file;
+ std::string file_name;
+ file_name.append(tmp_directory);
+ file_name.append(frame->name());
+ file_name.append(".xml");
+ xml_file.open(file_name.c_str(), std::ios::trunc);
+ libtest::Formatter::xml(*frame, xml_file);
+
Outn(); // Generate a blank to break up the messages if make check/test has been run
} while (exit_code == EXIT_SUCCESS and --opt_repeat);
}
std::cerr << "FATAL:" << e.what() << std::endl;
exit_code= EXIT_FAILURE;
}
+ catch (libtest::start& e)
+ {
+ std::cerr << "Failure to start:" << e.what() << std::endl;
+ exit_code= EXIT_FAILURE;
+ }
catch (libtest::disconnected& e)
{
std::cerr << "Unhandled disconnection occurred:" << e.what() << std::endl;
add_option(sasl());
}
- for (int x= 0 ; x < argc ; x++)
+ for (size_t x= 0 ; x < argc ; x++)
{
add_option(argv[x]);
}
#pragma once
+#define LIBTEST_FAIL_PORT 23
+
namespace libtest {
LIBTEST_API
}
#endif
+ if (port() == LIBTEST_FAIL_PORT)
+ {
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(), "Called failure");
+ }
+
if (getenv("YATL_PTRCHECK_SERVER"))
{
_app.use_ptrcheck();
if (args(_app) == false)
{
- Error << "Could not build command()";
- return false;
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(), "Could not build command()");
}
libtest::release_port(_port);
Application::error_t ret;
if (Application::SUCCESS != (ret= _app.run()))
{
- Error << "Application::run() " << ret;
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(), "Application::run() %s", libtest::Application::toString(ret));
return false;
}
_running= _app.print();
char buf[PATH_MAX];
char *getcwd_buf= getcwd(buf, sizeof(buf));
- throw libtest::fatal(LIBYATL_DEFAULT_PARAM,
- "Unable to open pidfile in %s for: %s stderr:%s",
- getcwd_buf ? getcwd_buf : "",
- _running.c_str(),
- _app.stderr_c_str());
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(),
+ "Unable to open pidfile in %s for: %s stderr:%s",
+ getcwd_buf ? getcwd_buf : "",
+ _running.c_str(),
+ _app.stderr_c_str());
}
}
}
uint32_t waited;
uint32_t retry;
- for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
+ for (waited= 0, retry= 4; ; retry++, waited+= this_wait)
{
if ((pinged= ping()) == true)
{
_app.slurp();
if (kill_file(pid_file()) == false)
{
- libtest::fatal err(LIBYATL_DEFAULT_PARAM,
- "Failed to kill off server, waited: %u after startup occurred, when pinging failed: %.*s stderr:%.*s",
- this_wait,
- int(_running.size()), _running.c_str(),
- int(_app.stderr_result_length()), _app.stderr_c_str());
-
- stream::cerr(err.file(), err.line(), err.func()) << err.what();
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(),
+ "Failed to kill off server, waited: %u after startup occurred, when pinging failed: %.*s stderr:%.*s",
+ this_wait,
+ int(_running.size()), _running.c_str(),
+ int(_app.stderr_result_length()), _app.stderr_c_str());
}
else
{
- libtest::fatal err(LIBYATL_DEFAULT_PARAM,
- "Failed native ping(), pid: %d was alive: %s waited: %u server started, having pid_file. exec: %.*s stderr:%.*s",
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(),
+ "Failed native ping(), pid: %d was alive: %s waited: %u server started, having pid_file. exec: %.*s stderr:%.*s",
+ int(_app.pid()),
+ _app.check() ? "true" : "false",
+ this_wait,
+ int(_running.size()), _running.c_str(),
+ int(_app.stderr_result_length()), _app.stderr_c_str());
+ }
+ }
+ else
+ {
+ throw libtest::start(LIBYATL_DEFAULT_PARAM,
+ hostname(), port(),
+ "Failed native ping(), pid: %d is alive: %s waited: %u server started. exec: %.*s stderr:%.*s",
int(_app.pid()),
_app.check() ? "true" : "false",
this_wait,
int(_running.size()), _running.c_str(),
int(_app.stderr_result_length()), _app.stderr_c_str());
-
- stream::cerr(err.file(), err.line(), err.func()) << err.what();
- }
- }
- else
- {
- libtest::fatal err(LIBYATL_DEFAULT_PARAM,
- "Failed native ping(), pid: %d is alive: %s waited: %u server started. exec: %.*s stderr:%.*s",
- int(_app.pid()),
- _app.check() ? "true" : "false",
- this_wait,
- int(_running.size()), _running.c_str(),
- int(_app.stderr_result_length()), _app.stderr_c_str());
-
- stream::cerr(err.file(), err.line(), err.func()) << err.what();
}
_running.clear();
+
return false;
}
}
}
}
+ catch (libtest::start err)
+ {
+ stream::cerr(err.file(), err.line(), err.func()) << err.what();
+ delete server;
+ return false;
+ }
+ catch (libtest::disconnected err)
+ {
+ stream::cerr(err.file(), err.line(), err.func()) << err.what();
+ delete server;
+ return false;
+ }
catch (...)
{
delete server;
return NULL;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework *world)
{
world->create(world_create);
}
#define test_zero(__actual) \
do \
{ \
- if (not libtest::_compare_zero(__FILE__, __LINE__, __func__, ((__actual)))) \
+ if (libtest::_compare_zero(__FILE__, __LINE__, __func__, ((__actual))) == false) \
{ \
libtest::create_core(); \
return TEST_FAILURE; \
test_skip(true, has_drizzled());
- test_true(server_startup(*servers, "drizzled", get_free_port(), 0, NULL));
+ test_skip(true, server_startup(*servers, "drizzled", get_free_port(), 0, NULL));
return TEST_SUCCESS;
}
test_skip(true, has_gearmand());
- test_true(server_startup(*servers, "gearmand", get_free_port(), 0, NULL));
+ test_skip(true, server_startup(*servers, "gearmand", get_free_port(), 0, NULL));
return TEST_SUCCESS;
}
+#if 0
static test_return_t memcached_light_cycle_TEST(void *object)
{
server_startup_st *servers= (server_startup_st*)object;
return TEST_SUCCESS;
}
+#endif
static test_return_t skip_shim(bool a, bool b)
{
return TEST_SUCCESS;
}
-static test_return_t test_skip_true_TEST(void *object)
+static test_return_t test_skip_true_TEST(void*)
{
test_compare(true, true);
test_compare(false, false);
return TEST_SUCCESS;
}
-static test_return_t test_skip_false_TEST(void *object)
+static test_return_t test_skip_false_TEST(void*)
{
test_compare(TEST_SKIPPED, skip_shim(true, false));
test_compare(TEST_SKIPPED, skip_shim(false, true));
return TEST_SUCCESS;
}
+static test_return_t server_startup_fail_TEST(void *object)
+{
+ server_startup_st *servers= (server_startup_st*)object;
+ test_true(servers);
+
+ test_compare(servers->start_server(testing_service, LIBTEST_FAIL_PORT, 0, NULL, true), false);
+
+ return TEST_SUCCESS;
+}
+
static test_return_t server_startup_TEST(void *object)
{
server_startup_st *servers= (server_startup_st*)object;
return TEST_SUCCESS;
}
+#if 0
static test_return_t memcached_sasl_test(void *object)
{
server_startup_st *servers= (server_startup_st*)object;
return TEST_SKIPPED;
}
+#endif
static test_return_t application_true_BINARY(void *)
{
const char *args[]= { "--fubar", 0 };
test_compare(Application::SUCCESS, true_app.run(args));
test_compare(Application::SUCCESS, true_app.wait());
- test_compare(0, true_app.stdout_result().size());
+ test_zero(true_app.stdout_result().size());
return TEST_SUCCESS;
}
test_compare(Application::INVALID, true_app.wait(false));
#endif
- test_compare(0, true_app.stdout_result().size());
+ test_zero(true_app.stdout_result().size());
return TEST_SUCCESS;
}
const char *args[]= { "--fubar=doh", 0 };
test_compare(Application::SUCCESS, true_app.run(args));
test_compare(Application::SUCCESS, true_app.wait());
- test_compare(0, true_app.stdout_result().size());
+ test_zero(true_app.stdout_result().size());
return TEST_SUCCESS;
}
test_compare(Application::SUCCESS, true_app.run());
test_compare(Application::SUCCESS, true_app.wait());
- test_compare(0, true_app.stdout_result().size());
+ test_zero(true_app.stdout_result().size());
return TEST_SUCCESS;
}
true_app.add_option("fubar");
test_compare(Application::SUCCESS, true_app.run());
- test_compare(Application::SUCCESS, true_app.wait(false));
+ test_compare(Application::SUCCESS, true_app.join());
libtest::vchar_t response;
make_vector(response, test_literal_param("fubar\n"));
Application touch_app("touch");
const char *args[]= { tmp.c_str(), 0 };
test_compare(Application::SUCCESS, touch_app.run(args));
- test_compare(Application::SUCCESS, touch_app.wait(false));
+ test_compare(Application::SUCCESS, touch_app.join());
test_compare(0, access(tmp.c_str(), R_OK));
test_compare(0, unlink(tmp.c_str()));
{
test_skip(true, HAVE_LIBGEARMAN);
test_skip(true, has_gearmand());
+
+ testing_service= "gearmand";
+
return TEST_SUCCESS;
}
{
test_skip(true, HAVE_LIBDRIZZLE);
test_skip(true, has_drizzled());
+
+ testing_service= "drizzled";
+
return TEST_SUCCESS;
}
#endif
{"gearmand startup-shutdown", 0, gearmand_cycle_test },
{"_compare(gearman_return_t)", 0, _compare_gearman_return_t_test },
+ {"server_startup(fail)", 0, server_startup_fail_TEST },
{0, 0, 0}
};
{"memcached startup-shutdown", 0, server_startup_TEST },
{"memcached(socket file) startup-shutdown", 0, socket_server_startup_TEST },
{"_compare(memcached_return_t)", 0, _compare_memcached_return_t_test },
+ {"server_startup(fail)", 0, server_startup_fail_TEST },
{0, 0, 0}
};
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework *world)
{
world->collections(collection);
world->create(world_create);
--- /dev/null
+https://github.com/BrianAker/m4
+
+Common m4 files that I use.
+ -Brian Aker, brian@tangent.org
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# For every FLAG1, FLAG2 it is checked whether the compiler works with the
+# flag. If it does, the flag is added FLAGS-VARIABLE
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. During the check the flag is always added to the
+# current language's flags.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# NOTE: This macro depends on the AX_APPEND_FLAG and
+# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
+# AX_APPEND_LINK_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[AC_REQUIRE([AX_CHECK_COMPILE_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
+for flag in $1; do
+ AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_APPEND_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
+AS_VAR_SET_IF(FLAGS,
+ [case " AS_VAR_GET(FLAGS) " in
+ *" $1 "*)
+ AC_RUN_LOG([: FLAGS already contains $1])
+ ;;
+ *)
+ AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+ AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
+ ;;
+ esac],
+ [AS_VAR_SET(FLAGS,["$1"])])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# For every FLAG1, FLAG2 it is checked whether the linker works with the
+# flag. If it does, the flag is added FLAGS-VARIABLE
+#
+# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is
+# used. During the check the flag is always added to the linker's flags.
+#
+# If EXTRA-FLAGS is defined, it is added to the linker's default flags
+# when the check is done. The check is thus made with the flags: "LDFLAGS
+# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
+# issue an error when a bad flag is given.
+#
+# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG.
+# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_APPEND_LINK_FLAGS],
+[AC_REQUIRE([AX_CHECK_LINK_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
+for flag in $1; do
+ AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
+done
+])dnl AX_APPEND_LINK_FLAGS
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the linker or gives an error.
+# (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the linker's default flags
+# when the check is done. The check is thus made with the flags: "LDFLAGS
+# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
+# issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS $4 $1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_HARDEN_COMPILER_FLAGS
+#
+# DESCRIPTION
+#
+# Any compiler flag that "hardens" or tests code.
+#
+# NOTE: Implementation based on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+# Copyright (C) 2012 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.
+
+#serial 1
+
+AC_DEFUN([AX_HARDEN_COMPILER_FLAGS],
+[AC_REQUIRE([AX_CHECK_COMPILE_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
+AC_REQUIRE([AX_CHECK_LINK_FLAG])
+AX_APPEND_COMPILE_FLAGS([-O2])
+AX_APPEND_COMPILE_FLAGS([-Werror])
+AX_APPEND_COMPILE_FLAGS([-Wall])
+AX_APPEND_COMPILE_FLAGS([-Wextra])
+AX_APPEND_COMPILE_FLAGS([-Wmaybe-uninitialized])
+AX_APPEND_COMPILE_FLAGS([-Wsign-compare])
+AX_APPEND_COMPILE_FLAGS([-Wunused-result])
+AX_APPEND_COMPILE_FLAGS([-Wunused-variable])
+AX_APPEND_COMPILE_FLAGS([-floop-parallelize-all])
+AX_APPEND_COMPILE_FLAGS([-fstack-protector-all])
+AX_APPEND_COMPILE_FLAGS([-ggdb])
+AX_APPEND_COMPILE_FLAGS([-fstack-protector-all])
+AX_APPEND_COMPILE_FLAGS([-Wstack-protector])
+AX_APPEND_COMPILE_FLAGS([-fwrapv])
+AX_APPEND_COMPILE_FLAGS([-D_FORTIFY_SOURCE=2])
+AX_APPEND_COMPILE_FLAGS([--param],[ssp-buffer-size=1])
+AX_CHECK_LINK_FLAG([-Werror])
+AX_CHECK_LINK_FLAG([-z relro -z now])
+])dnl AX_HARDEN_COMPILER_FLAGS
--- /dev/null
+update_m4:
+ @rm -r -f m4.moved
+ @mv m4 m4.moved
+ @git clone git@github.com:BrianAker/m4.git
+ @bzr revert m4
+ (cd m4; git checkout .)
+ @bzr diff m4
+++ /dev/null
-Dependencies:
-
- -- libevent, http://www.monkey.org/~provos/libevent/ (libevent-dev)
-
-If using Linux, you need a kernel with epoll. Sure, libevent will
-work with normal select, but it sucks.
-
-epoll isn't in Linux 2.4, but there's a backport at:
-
- http://www.xmailserver.org/linux-patches/nio-improve.html
-
-You want the epoll-lt patch (level-triggered).
-
-If you're using MacOS, you'll want libevent 1.1 or higher to deal with
-a kqueue bug.
-
-Also, be warned that the -k (mlockall) option to memcached might be
-dangerous when using a large cache. Just make sure the memcached machines
-don't swap. memcached does non-blocking network I/O, but not disk. (it
-should never go to disk, or you've lost the whole point of it)
-
-The memcached website is at:
-
- http://www.memcached.org
-
-Want to contribute? Up-to-date pointers should be at:
-
- http://contributing.appspot.com/memcached
--- /dev/null
+# Memcached
+
+## Dependencies
+
+* libevent, http://www.monkey.org/~provos/libevent/ (libevent-dev)
+
+## Environment
+
+### Linux
+
+If using Linux, you need a kernel with epoll. Sure, libevent will
+work with normal select, but it sucks.
+
+epoll isn't in Linux 2.4, but there's a backport at:
+
+ http://www.xmailserver.org/linux-patches/nio-improve.html
+
+You want the epoll-lt patch (level-triggered).
+
+### Mac OS X
+
+If you're using MacOS, you'll want libevent 1.1 or higher to deal with
+a kqueue bug.
+
+Also, be warned that the -k (mlockall) option to memcached might be
+dangerous when using a large cache. Just make sure the memcached machines
+don't swap. memcached does non-blocking network I/O, but not disk. (it
+should never go to disk, or you've lost the whole point of it)
+
+## Website
+
+* http://www.memcached.org
+
+## Contributing
+
+Want to contribute? Up-to-date pointers should be at:
+
+* http://contributing.appspot.com/memcached
*/
#include "memcached.h"
-
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/signal.h>
static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER;
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wstrict-aliasing"
-#endif
-
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
typedef unsigned char ub1; /* unsigned 1-byte quantities */
pthread_cond_wait(&maintenance_cond, &cache_lock);
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
return NULL;
}
mutex_lock(&cache_lock);
do_run_maintenance_thread = 0;
pthread_cond_signal(&maintenance_cond);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
/* Wait for the maintenance thread to stop */
pthread_join(maintenance_tid, NULL);
echo "automake..."
if test x$AUTOMAKE = x; then
- AUTOMAKE=`locate_binary automake-1.11 automake-1.10 automake-1.9 automake-1.7`
+ AUTOMAKE=`locate_binary automake-1.12 automake-1.11 automake-1.10 automake-1.9 automake-1.7`
if test x$AUTOMAKE = x; then
die "Did not find a supported automake"
fi
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#include "memcached.h"
+#include <config.h>
#include <stdlib.h>
#include <string.h>
free(cache->name);
free(cache->ptr);
pthread_mutex_destroy(&cache->mutex);
+ free(cache);
}
void* cache_alloc(cache_t *cache) {
* SUCH DAMAGE.
*/
+#include <config.h>
+
#if defined __SUNPRO_C || defined __DECC || defined __HP_cc
# pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $"
# pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $"
#endif
-#include "memcached.h"
-
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include "memcached.h"
+
int daemonize(int nochdir, int noclose)
{
int fd;
use FindBin qw($Bin);
chdir "$Bin/.." or die;
-my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am);
+my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am README README.md);
push(@exempted, glob("doc/*.xml"));
push(@exempted, glob("doc/xml2rfc/*.xsl"));
push(@exempted, glob("m4/*backport*m4"));
- <source class> is an id number for the slab class to steal a page from
+A source class id of -1 means "pick from any valid class"
+
- <dest class> is an id number for the slab class to move a page to
The response line could be one of:
The automover can be enabled or disabled at runtime with this command.
-slabs automove <1|0>
+slabs automove <0|1>
-- 1|0 is the indicator on whether to enable the slabs automover or not.
+- 0|1|2 is the indicator on whether to enable the slabs automover or not.
The response should always be "OK\r\n"
+- <0> means to set the thread on standby
+
+- <1> means to run the builtin slow algorithm to choose pages to move
+
+- <2> is a highly aggressive mode which causes pages to be moved every time
+ there is an eviction. It is not recommended to run for very long in this
+ mode unless your access patterns are very well understood.
+
Statistics
----------
stats <args>\r\n
Depending on <args>, various internal data is sent by the server. The
-kinds of arguments and the data sent are not documented in this vesion
+kinds of arguments and the data sent are not documented in this version
of the protocol, and are subject to change for the convenience of
memcache developers.
* whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG
* are set in the configure script.
*/
-#if defined(ENDIAN_BIG) && ENDIAN_BIG == 1
+#if ENDIAN_BIG == 1
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 1
#else
-# if defined(ENDIAN_LITTLE) && ENDIAN_LITTLE == 1
+# if ENDIAN_LITTLE == 1
# define HASH_LITTLE_ENDIAN 1
# define HASH_BIG_ENDIAN 0
# else
case 2 : a+=k[0]&0xffff; break;
case 1 : a+=k[0]&0xff; break;
case 0 : return c; /* zero length strings require no mixing */
- default:
- abort();
}
#else /* make valgrind happy */
case 1 : a+=k8[0];
break;
case 0 : return c; /* zero length strings require no mixing */
- default:
- abort();
}
} else { /* need to read the key one byte at a time */
case 1 : a+=k[0];
break;
case 0 : return c; /* zero length strings require no mixing */
- default:
- abort();
}
}
void item_stats_reset(void) {
mutex_lock(&cache_lock);
memset(itemstats, 0, sizeof(itemstats));
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
} else if ((it = slabs_alloc(ntotal, id)) == NULL) {
if (settings.evict_to_free == 0) {
itemstats[id].outofmemory++;
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
return NULL;
}
itemstats[id].evicted++;
do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0));
/* Initialize the item block: */
it->slabs_clsid = 0;
+
+ /* If we've just evicted an item, and the automover is set to
+ * angry bird mode, attempt to rip memory into this slab class.
+ * TODO: Move valid object detection into a function, and on a
+ * "successful" memory pull, look behind and see if the next alloc
+ * would be an eviction. Then kick off the slab mover before the
+ * eviction happens.
+ */
+ if (settings.slab_automove == 2)
+ slabs_reassign(-1, id);
} else {
refcount_decr(&search->refcount);
}
search->refcount = 1;
do_item_unlink_nolock(search, hash(ITEM_key(search), search->nkey, 0));
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
return NULL;
}
* been removed from the slab LRU.
*/
it->refcount = 1; /* the caller will have a reference */
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
it->next = it->prev = it->h_next = 0;
it->slabs_clsid = id;
assoc_insert(it, hv);
item_link_q(it);
refcount_incr(&it->refcount);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
return 1;
}
item_unlink_q(it);
do_item_remove(it);
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
/* FIXME: Is it necessary to keep this copy/pasted code? */
it->time = current_time;
item_link_q(it);
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
}
return do_item_link(new_it, hv);
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
-
/*@null@*/
char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes) {
unsigned int memlimit = 2 * 1024 * 1024; /* 2MB max response size */
for (i = 0; i < LARGEST_ID; i++) {
evicted[i] = itemstats[i].evicted;
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
void do_item_stats(ADD_STAT add_stats, void *c) {
it = NULL;
}
}
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
int was_found = 0;
if (settings.verbose > 2) {
*/
static volatile bool allow_new_conns = true;
static struct event maxconnsevent;
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
static void maxconns_handler(const int fd, const short which, void *arg) {
struct timeval t = {.tv_sec = 0, .tv_usec = 10000};
settings.maxconns_fast = false;
settings.hashpower_init = 0;
settings.slab_reassign = false;
- settings.slab_automove = false;
+ settings.slab_automove = 0;
}
/*
}
static const char *prot_text(enum protocol prot) {
- const char *rv = "unknown";
+ char *rv = "unknown";
switch(prot) {
case ascii_prot:
rv = "ascii";
case negotiating_prot:
rv = "auto-negotiate";
break;
- default:
- abort();
}
return rv;
}
return statenames[state];
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
/*
* Sets a connection's current state in the state machine. Any special
* processing that needs to happen on certain state transitions can
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wsign-compare"
-#endif
static void out_string(conn *c, const char *str) {
size_t len;
case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR:
errstr = "Auth failure.";
break;
- case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE:
- assert(false);
- case PROTOCOL_BINARY_RESPONSE_SUCCESS:
- assert(false);
default:
assert(false);
errstr = "UNHANDLED ERROR";
}
/* Form and send a response to a command over the binary protocol */
-static void write_bin_response(conn *c, const void *d, int hlen, int keylen, int dlen) {
+static void write_bin_response(conn *c, void *d, int hlen, int keylen, int dlen) {
if (!c->noreply || c->cmd == PROTOCOL_BINARY_CMD_GET ||
c->cmd == PROTOCOL_BINARY_CMD_GETK) {
add_bin_header(c, 0, hlen, keylen, dlen);
case DELTA_ITEM_CAS_MISMATCH:
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0);
break;
-
- default:
- assert(0);
- abort();
}
}
eno = PROTOCOL_BINARY_RESPONSE_NOT_STORED;
}
write_bin_error(c, eno, 0);
- default:
- assert(false);
- abort();
}
item_remove(c->item); /* release the c->item reference */
protocol_binary_response_get* rsp = (protocol_binary_response_get*)c->wbuf;
char* key = binary_get_key(c);
size_t nkey = c->binary_header.request.keylen;
- protocol_binary_request_touch *t = (void *)&c->binary_header;
- uint32_t exptime = ntohl(t->message.body.expiration);
+ protocol_binary_request_touch *t = binary_get_request(c);
+ time_t exptime = ntohl(t->message.body.expiration);
if (settings.verbose > 1) {
int ii;
}
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
static void append_bin_stats(const char *key, const uint16_t klen,
const char *val, const uint32_t vlen,
conn *c) {
uint32_t bodylen = klen + vlen;
protocol_binary_response_header header = {
.response.magic = (uint8_t)PROTOCOL_BINARY_RES,
- .response.opcode = (uint8_t)PROTOCOL_BINARY_CMD_STAT,
+ .response.opcode = PROTOCOL_BINARY_CMD_STAT,
.response.keylen = (uint16_t)htons(klen),
- .response.extlen = (uint8_t)0,
.response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES,
- .response.status = (uint16_t)0,
.response.bodylen = htonl(bodylen),
- .response.opaque = c->opaque,
- .response.cas = (uint64_t)0
+ .response.opaque = c->opaque
};
memcpy(buf, header.bytes, sizeof(header.response));
switch (c->cmd) {
case PROTOCOL_BINARY_CMD_VERSION:
if (extlen == 0 && keylen == 0 && bodylen == 0) {
- write_bin_response(c, RVERSION, 0, 0, strlen(RVERSION));
+ write_bin_response(c, VERSION, 0, 0, strlen(VERSION));
} else {
protocol_error = 1;
}
case bin_reading_sasl_auth_data:
process_bin_complete_sasl_auth(c);
break;
- case bin_reading_cas_header:
- assert(0);
- case bin_no_state:
- assert(0);
default:
fprintf(stderr, "Not handling substate %d\n", c->substate);
assert(0);
APPEND_STAT("pid", "%lu", (long)pid);
APPEND_STAT("uptime", "%u", now);
APPEND_STAT("time", "%ld", now + (long)process_started);
- APPEND_STAT("version", "%s", RVERSION);
+ APPEND_STAT("version", "%s", VERSION);
APPEND_STAT("libevent", "%s", event_get_version());
APPEND_STAT("pointer_size", "%d", (int)(8 * sizeof(void *)));
APPEND_STAT("maxconns_fast", "%s", settings.maxconns_fast ? "yes" : "no");
APPEND_STAT("hashpower_init", "%d", settings.hashpower_init);
APPEND_STAT("slab_reassign", "%s", settings.slab_reassign ? "yes" : "no");
- APPEND_STAT("slab_automove", "%s", settings.slab_automove ? "yes" : "no");
+ APPEND_STAT("slab_automove", "%d", settings.slab_automove);
}
static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
}
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
-#endif
/* ntokens is overwritten here... shrug.. */
static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, bool return_cas) {
char *key;
break;
case DELTA_ITEM_CAS_MISMATCH:
break; /* Should never get here */
- default:
- assert(false);
- abort();
}
}
need to update the CAS on the existing item. */
mutex_lock(&cache_lock); /* FIXME */
ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
memcpy(ITEM_data(it), buf, res);
memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2);
level = strtoul(tokens[2].value, NULL, 10);
if (level == 0) {
- settings.slab_automove = false;
- } else if (level == 1) {
- settings.slab_automove = true;
+ settings.slab_automove = 0;
+ } else if (level == 1 || level == 2) {
+ settings.slab_automove = level;
} else {
out_string(c, "ERROR");
return;
} else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "version") == 0)) {
- out_string(c, "VERSION " RVERSION);
+ out_string(c, "VERSION " VERSION);
} else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "quit") == 0)) {
case REASSIGN_NOSPARE:
out_string(c, "NOSPARE source class has no spare pages");
break;
- case REASSIGN_DEST_NOT_FULL:
- out_string(c, "NOTFULL dest class has spare memory");
- break;
- case REASSIGN_SRC_NOT_SAFE:
- out_string(c, "UNSAFE src class is in an unsafe state");
- break;
case REASSIGN_SRC_DST_SAME:
out_string(c, "SAME src and dst class are identical");
break;
- default:
- assert(false);
- abort();
}
return;
} else if (ntokens == 4 &&
case READ_MEMORY_ERROR: /* Failed to allocate more memory */
/* State already set by try_read_network */
break;
- default:
- assert(false);
- abort();
}
break;
case TRANSMIT_SOFT_ERROR:
stop = true;
break;
- default:
- assert(false);
- abort();
}
break;
case conn_max_state:
assert(false);
break;
- default:
- assert(false);
- abort();
}
}
}
#endif
- error = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
- if (error != 0)
- {
- perror("setsockopt(SO_REUSEADDR)");
- }
-
+ setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
if (IS_UDP(transport)) {
maximize_sndbuf(sfd);
} else {
}
static void usage(void) {
- printf(RPACKAGE " " RVERSION "\n");
+ printf(PACKAGE " " VERSION "\n");
printf("-p <num> TCP port number to listen on (default: 11211)\n"
"-U <num> UDP port number to listen on (default: 11211, 0 is off)\n"
"-s <file> UNIX socket path to listen on (disables network support)\n"
}
static void usage_license(void) {
- printf(RPACKAGE " " RVERSION "\n\n");
+ printf(PACKAGE " " VERSION "\n\n");
printf(
"Copyright (c) 2003, Danga Interactive, Inc. <http://www.danga.com/>\n"
"All rights reserved.\n"
return ret;
#else
- return 0;
+ return -1;
#endif
}
SLAB_AUTOMOVE
};
char *const subopts_tokens[] = {
- [MAXCONNS_FAST] = (char*)"maxconns_fast",
- [HASHPOWER_INIT] = (char*)"hashpower",
- [SLAB_REASSIGN] = (char*)"slab_reassign",
- [SLAB_AUTOMOVE] = (char*)"slab_automove",
+ [MAXCONNS_FAST] = "maxconns_fast",
+ [HASHPOWER_INIT] = "hashpower",
+ [SLAB_REASSIGN] = "slab_reassign",
+ [SLAB_AUTOMOVE] = "slab_automove",
NULL
};
case 'L' :
if (enable_large_pages() == 0) {
preallocate = true;
+ } else {
+ fprintf(stderr, "Cannot enable large pages on this system\n"
+ "(There is no Linux support as of this version)\n");
+ return 1;
}
break;
case 'C' :
settings.slab_reassign = true;
break;
case SLAB_AUTOMOVE:
- settings.slab_automove = true;
+ if (subopts_value == NULL) {
+ settings.slab_automove = 1;
+ break;
+ }
+ settings.slab_automove = atoi(subopts_value);
+ if (settings.slab_automove < 0 || settings.slab_automove > 2) {
+ fprintf(stderr, "slab_automove must be between 0 and 2\n");
+ return 1;
+ }
break;
default:
printf("Illegal suboption \"%s\"\n", subopts_value);
stop_assoc_maintenance_thread();
/* remove the PID file if we're a daemon */
-#if 0
if (do_daemonize)
remove_pidfile(pid_file);
-#endif
/* Clean up strdup() call for bind() address */
if (settings.inter)
free(settings.inter);
#endif
#include <stdbool.h>
-#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#define POWER_SMALLEST 1
#define POWER_LARGEST 200
#define CHUNK_ALIGN_BYTES 8
-#define DONT_PREALLOC_SLABS
#define MAX_NUMBER_OF_SLAB_CLASSES (POWER_LARGEST + 1)
/** How long an object can reasonably be assumed to be locked before
bool sasl; /* SASL on/off */
bool maxconns_fast; /* Whether or not to early close connections */
bool slab_reassign; /* Whether or not slab reassignment is allowed */
- bool slab_automove; /* Whether or not to automatically move slabs */
+ int slab_automove; /* Whether or not to automatically move slabs */
int hashpower_init; /* Starting hash power level */
};
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
extern struct stats stats;
extern time_t process_started;
extern struct settings settings;
#define ITEM_FETCHED 8
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
/**
* Structure for storing items within memcached.
*/
enum store_item_type store_item(item *item, int comm, conn *c);
-#if defined(HAVE_DROP_PRIVILEGES) && HAVE_DROP_PRIVILEGES
+#if HAVE_DROP_PRIVILEGES
extern void drop_privileges(void);
#else
#define drop_privileges()
%files
%defattr(-,root,root,-)
-%doc AUTHORS ChangeLog COPYING NEWS README doc/CONTRIBUTORS doc/*.txt
+%doc AUTHORS ChangeLog COPYING NEWS README.md doc/CONTRIBUTORS doc/*.txt
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
%dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached
*/
probe command__append(int connid, const char *key, int keylen, int size, int64_t casid);
+ /**
+ * Fired for an touch-command.
+ * @param connid connection id
+ * @param key requested key
+ * @param keylen length of the key
+ * @param size the new size of the key's data (or signed int -1 if
+ * not found)
+ * @param casid the casid for the item
+ */
+ probe command__touch(int connid, const char *key, int keylen, int size, int64_t casid);
+
/**
* Fired for a cas-command.
* @param connid connection id
void *slots; /* list of item ptrs */
unsigned int sl_curr; /* total free items in list */
- void *end_page_ptr; /* pointer to next free item at end of page, or 0 */
- unsigned int end_page_free; /* number of items remaining at end of last alloced page */
-
unsigned int slabs; /* how many slabs were allocated for this class */
void **slab_list; /* array of slab pointers */
* Access to the slab allocator is protected by this lock
*/
static pthread_mutex_t slabs_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t slabs_rebalance_lock = PTHREAD_MUTEX_INITIALIZER;
/*
* Forward Declarations
*/
static int do_slabs_newslab(const unsigned int id);
static void *memory_allocate(size_t size);
+static void do_slabs_free(void *ptr, const size_t size, unsigned int id);
-#ifndef DONT_PREALLOC_SLABS
/* Preallocate as many slab pages as possible (called from slabs_init)
on start-up, so users don't get confused out-of-memory errors when
they do have free (in-slab) space, but no space to make new slabs.
slab types can be made. if max memory is less than 18 MB, only the
smaller ones will be made. */
static void slabs_preallocate (const unsigned int maxslabs);
-#endif
/*
* Figures out which slab class (chunk size) is required to store an item of
}
-#ifndef DONT_PREALLOC_SLABS
- {
- char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");
-
- if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
- slabs_preallocate(power_largest);
- }
+ if (prealloc) {
+ slabs_preallocate(power_largest);
}
-#endif
}
-#ifndef DONT_PREALLOC_SLABS
static void slabs_preallocate (const unsigned int maxslabs) {
int i;
unsigned int prealloc = 0;
for (i = POWER_SMALLEST; i <= POWER_LARGEST; i++) {
if (++prealloc > maxslabs)
return;
- do_slabs_newslab(i);
+ if (do_slabs_newslab(i) == 0) {
+ fprintf(stderr, "Error while preallocating slab memory!\n"
+ "If using -L or other prealloc options, max memory must be "
+ "at least %d megabytes.\n", power_largest);
+ exit(1);
+ }
}
}
-#endif
static int grow_slab_list (const unsigned int id) {
slabclass_t *p = &slabclass[id];
return 1;
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wsign-compare"
-#endif
+static void split_slab_page_into_freelist(char *ptr, const unsigned int id) {
+ slabclass_t *p = &slabclass[id];
+ int x;
+ for (x = 0; x < p->perslab; x++) {
+ do_slabs_free(ptr, 0, id);
+ ptr += p->size;
+ }
+}
static int do_slabs_newslab(const unsigned int id) {
slabclass_t *p = &slabclass[id];
}
memset(ptr, 0, (size_t)len);
- p->end_page_ptr = ptr;
- p->end_page_free = p->perslab;
+ split_slab_page_into_freelist(ptr, id);
p->slab_list[p->slabs++] = ptr;
mem_malloced += len;
p = &slabclass[id];
assert(p->sl_curr == 0 || ((item *)p->slots)->slabs_clsid == 0);
-#ifdef USE_SYSTEM_MALLOC
- if (mem_limit && mem_malloced + size > mem_limit) {
- MEMCACHED_SLABS_ALLOCATE_FAILED(size, id);
- return 0;
- }
- mem_malloced += size;
- ret = malloc(size);
- MEMCACHED_SLABS_ALLOCATE(size, id, 0, ret);
- return ret;
-#endif
-
/* fail unless we have space at the end of a recently allocated page,
we have something on our freelist, or we could allocate a new page */
- if (! (p->end_page_ptr != 0 || p->sl_curr != 0 ||
- do_slabs_newslab(id) != 0)) {
+ if (! (p->sl_curr != 0 || do_slabs_newslab(id) != 0)) {
/* We don't have more memory available */
ret = NULL;
} else if (p->sl_curr != 0) {
if (it->next) it->next->prev = 0;
p->sl_curr--;
ret = (void *)it;
- } else {
- /* if we recently allocated a whole page, return from that */
- assert(p->end_page_ptr != NULL);
- ret = p->end_page_ptr;
- if (--p->end_page_free != 0) {
- p->end_page_ptr = ((caddr_t)p->end_page_ptr) + p->size;
- } else {
- p->end_page_ptr = 0;
- }
}
if (ret) {
MEMCACHED_SLABS_FREE(size, id, ptr);
p = &slabclass[id];
-#ifdef USE_SYSTEM_MALLOC
- mem_malloced -= size;
- free(ptr);
- return;
-#endif
-
it = (item *)ptr;
it->it_flags |= ITEM_SLABBED;
it->prev = 0;
APPEND_NUM_STAT(i, "total_pages", "%u", slabs);
APPEND_NUM_STAT(i, "total_chunks", "%u", slabs * perslab);
APPEND_NUM_STAT(i, "used_chunks", "%u",
- slabs*perslab - p->sl_curr - p->end_page_free);
+ slabs*perslab - p->sl_curr);
APPEND_NUM_STAT(i, "free_chunks", "%u", p->sl_curr);
- APPEND_NUM_STAT(i, "free_chunks_end", "%u", p->end_page_free);
+ /* Stat is dead, but displaying zero instead of removing it. */
+ APPEND_NUM_STAT(i, "free_chunks_end", "%u", 0);
APPEND_NUM_STAT(i, "mem_requested", "%llu",
(unsigned long long)p->requested);
APPEND_NUM_STAT(i, "get_hits", "%llu",
}
static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t slab_rebalance_cond = PTHREAD_COND_INITIALIZER;
static volatile int do_run_slab_thread = 1;
+static volatile int do_run_slab_rebalance_thread = 1;
#define DEFAULT_SLAB_BULK_CHECK 1
int slab_bulk_check = DEFAULT_SLAB_BULK_CHECK;
static int slab_rebalance_start(void) {
slabclass_t *s_cls;
- slabclass_t *d_cls;
int no_go = 0;
pthread_mutex_lock(&cache_lock);
no_go = -2;
s_cls = &slabclass[slab_rebal.s_clsid];
- d_cls = &slabclass[slab_rebal.d_clsid];
- if (d_cls->end_page_ptr || s_cls->end_page_ptr ||
- !grow_slab_list(slab_rebal.d_clsid)) {
+ if (!grow_slab_list(slab_rebal.d_clsid)) {
no_go = -1;
}
break;
case MOVE_PASS:
break;
- default:
- assert(false);
- abort();
}
slab_rebal.slab_pos = (char *)slab_rebal.slab_pos + s_cls->size;
memset(slab_rebal.slab_start, 0, (size_t)settings.item_size_max);
d_cls->slab_list[d_cls->slabs++] = slab_rebal.slab_start;
- d_cls->end_page_ptr = slab_rebal.slab_start;
- d_cls->end_page_free = d_cls->perslab;
+ split_slab_page_into_freelist(slab_rebal.slab_start,
+ slab_rebal.d_clsid);
slab_rebal.done = 0;
slab_rebal.s_clsid = 0;
return 0;
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
/* Slab rebalancer thread.
* Does not use spinlocks since it is not timing sensitive. Burn less CPU and
* go to sleep if locks are contended
*/
static void *slab_maintenance_thread(void *arg) {
- int was_busy = 0;
int src, dest;
while (do_run_slab_thread) {
+ if (settings.slab_automove == 1) {
+ if (slab_automove_decision(&src, &dest) == 1) {
+ /* Blind to the return codes. It will retry on its own */
+ slabs_reassign(src, dest);
+ }
+ sleep(1);
+ } else {
+ /* Don't wake as often if we're not enabled.
+ * This is lazier than setting up a condition right now. */
+ sleep(5);
+ }
+ }
+ return NULL;
+}
+
+/* Slab mover thread.
+ * Sits waiting for a condition to jump off and shovel some memory about
+ */
+static void *slab_rebalance_thread(void *arg) {
+ int was_busy = 0;
+
+ while (do_run_slab_rebalance_thread) {
if (slab_rebalance_signal == 1) {
if (slab_rebalance_start() < 0) {
/* Handle errors with more specifity as required. */
slab_rebalance_signal = 0;
}
+ was_busy = 0;
} else if (slab_rebalance_signal && slab_rebal.slab_start != NULL) {
- /* If we have a decision to continue, continue it */
was_busy = slab_rebalance_move();
- } else if (settings.slab_automove && slab_automove_decision(&src, &dest) == 1) {
- /* Blind to the return codes. It will retry on its own */
- slabs_reassign(src, dest);
}
if (slab_rebal.done) {
slab_rebalance_finish();
+ } else if (was_busy) {
+ /* Stuck waiting for some items to unlock, so slow down a bit
+ * to give them a chance to free up */
+ usleep(50);
}
- /* Sleep a bit if no work to do, or waiting on busy objects */
- if (was_busy || !slab_rebalance_signal)
- sleep(1);
+ if (slab_rebalance_signal == 0) {
+ /* always hold this lock while we're running */
+ pthread_cond_wait(&slab_rebalance_cond, &slabs_rebalance_lock);
+ }
}
return NULL;
}
+/* Iterate at most once through the slab classes and pick a "random" source.
+ * I like this better than calling rand() since rand() is slow enough that we
+ * can just check all of the classes once instead.
+ */
+static int slabs_reassign_pick_any(int dst) {
+ static int cur = POWER_SMALLEST - 1;
+ int tries = power_largest - POWER_SMALLEST + 1;
+ for (; tries > 0; tries--) {
+ cur++;
+ if (cur > power_largest)
+ cur = POWER_SMALLEST;
+ if (cur == dst)
+ continue;
+ if (slabclass[cur].slabs > 1) {
+ return cur;
+ }
+ }
+ return -1;
+}
+
static enum reassign_result_type do_slabs_reassign(int src, int dst) {
if (slab_rebalance_signal != 0)
return REASSIGN_RUNNING;
if (src == dst)
return REASSIGN_SRC_DST_SAME;
+ /* Special indicator to choose ourselves. */
+ if (src == -1) {
+ src = slabs_reassign_pick_any(dst);
+ /* TODO: If we end up back at -1, return a new error type */
+ }
+
if (src < POWER_SMALLEST || src > power_largest ||
dst < POWER_SMALLEST || dst > power_largest)
return REASSIGN_BADCLASS;
if (slabclass[src].slabs < 2)
return REASSIGN_NOSPARE;
- if (slabclass[dst].end_page_ptr)
- return REASSIGN_DEST_NOT_FULL;
-
- if (slabclass[src].end_page_ptr)
- return REASSIGN_SRC_NOT_SAFE;
-
slab_rebal.s_clsid = src;
slab_rebal.d_clsid = dst;
slab_rebalance_signal = 1;
+ pthread_cond_signal(&slab_rebalance_cond);
return REASSIGN_OK;
}
enum reassign_result_type slabs_reassign(int src, int dst) {
enum reassign_result_type ret;
- mutex_lock(&slabs_lock);
+ if (pthread_mutex_trylock(&slabs_rebalance_lock) != 0) {
+ return REASSIGN_RUNNING;
+ }
ret = do_slabs_reassign(src, dst);
- pthread_mutex_unlock(&slabs_lock);
+ pthread_mutex_unlock(&slabs_rebalance_lock);
return ret;
}
static pthread_t maintenance_tid;
+static pthread_t rebalance_tid;
int start_slab_maintenance_thread(void) {
int ret;
slab_bulk_check = DEFAULT_SLAB_BULK_CHECK;
}
}
+
+ if (pthread_cond_init(&slab_rebalance_cond, NULL) != 0) {
+ fprintf(stderr, "Can't intiialize rebalance condition\n");
+ return -1;
+ }
+ pthread_mutex_init(&slabs_rebalance_lock, NULL);
+
if ((ret = pthread_create(&maintenance_tid, NULL,
slab_maintenance_thread, NULL)) != 0) {
- fprintf(stderr, "Can't create thread: %s\n", strerror(ret));
+ fprintf(stderr, "Can't create slab maint thread: %s\n", strerror(ret));
+ return -1;
+ }
+ if ((ret = pthread_create(&rebalance_tid, NULL,
+ slab_rebalance_thread, NULL)) != 0) {
+ fprintf(stderr, "Can't create rebal thread: %s\n", strerror(ret));
return -1;
}
return 0;
void stop_slab_maintenance_thread(void) {
mutex_lock(&cache_lock);
do_run_slab_thread = 0;
+ do_run_slab_rebalance_thread = 0;
pthread_cond_signal(&maintenance_cond);
pthread_mutex_unlock(&cache_lock);
/* Wait for the maintenance thread to stop */
pthread_join(maintenance_tid, NULL);
+ pthread_join(rebalance_tid, NULL);
}
* 0 means error: can't store such a large object
*/
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
unsigned int slabs_clsid(const size_t size);
/** Allocate object of given length. 0 on error */ /*@null@*/
enum reassign_result_type {
REASSIGN_OK=0, REASSIGN_RUNNING, REASSIGN_BADCLASS, REASSIGN_NOSPARE,
- REASSIGN_DEST_NOT_FULL, REASSIGN_SRC_NOT_SAFE, REASSIGN_SRC_DST_SAME
+ REASSIGN_SRC_DST_SAME
};
enum reassign_result_type slabs_reassign(int src, int dst);
use strict;
use warnings;
-use Test::More tests => 3539;
+use Test::More tests => 3549;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;
$check->("totouch", 0, "toast2");
# Test miss as well
+ $mc->set("totouch", "toast3", 0, 1);
+ $res = $mc->touch("totouch", 1);
+ sleep 3;
+ $empty->("totouch");
}
# diag "Silent set.";
use strict;
use warnings;
-use Test::More tests => 131;
+use Test::More tests => 130;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;
ok($slabs_before->{"25:total_pages"} != $slabs_after->{"25:total_pages"},
"slab 25 pagecount changed");
-# Try to move another slab, see that it complains
+# Try to move another slab, see that you can move two in a row
print $sock "slabs reassign 31 25\r\n";
-like(scalar <$sock>, qr/^NOTFULL/, "Cannot re-run against class with empty space");
+like(scalar <$sock>, qr/^OK/, "Cannot re-run against class with empty space");
# Try to move a page backwards. Should complain that source class isn't "safe"
# to move from.
-print $sock "slabs reassign 25 31\r\n";
-like(scalar <$sock>, qr/^UNSAFE/, "Cannot move an unsafe slab back");
+# TODO: Wait until the above command completes, then try to move it back?
+# Seems pointless...
+#print $sock "slabs reassign 25 31\r\n";
+#like(scalar <$sock>, qr/^UNSAFE/, "Cannot move an unsafe slab back");
# Try to insert items into both slabs
print $sock "set bfoo51 0 0 70000\r\n", $bigdata, "\r\n";
BEGIN {
chdir "$Bin/.." or die;
- my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am);
+ my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am README README.md);
push(@exempted, glob("doc/*.xml"));
push(@exempted, glob("doc/xml2rfc/*.xsl"));
push(@exempted, glob("m4/*backport*m4"));
+ push(@exempted, glob("*.orig"));
my %exempted_hash = map { $_ => 1 } @exempted;
my @stuff = split /\0/, `git ls-files -z -c -m -o --exclude-standard`;
use Test::More tests => scalar(@files);
foreach my $f (@files) {
- open(my $fh, $f) or die;
+ open(my $fh, $f) or die "Cannot open file $f: $!";
my $before = do { local $/; <$fh>; };
close ($fh);
my $after = $before;
if (daemon) {
/* loop and wait for the pid file.. There is a potential race
* condition that the server just created the file but isn't
- * finished writing the content, but I'll take the chance....
- */
+ * finished writing the content, so we loop a few times
+ * reading as well */
while (access(pid_file, F_OK) == -1) {
usleep(10);
}
strerror(errno));
assert(false);
}
- assert(fgets(buffer, sizeof(buffer), fp) != NULL);
+
+ /* Avoid race by retrying 20 times */
+ for (int x = 0; x < 20 && fgets(buffer, sizeof(buffer), fp) == NULL; x++) {
+ usleep(10);
+ }
fclose(fp);
int32_t val;
mutex_lock(&atomics_mutex);
(*refcount)++;
res = *refcount;
- pthread_mutex_unlock(&atomics_mutex);
+ mutex_unlock(&atomics_mutex);
return res;
#endif
}
mutex_lock(&atomics_mutex);
(*refcount)--;
res = *refcount;
- pthread_mutex_unlock(&atomics_mutex);
+ mutex_unlock(&atomics_mutex);
return res;
#endif
}
}
void item_unlock(uint32_t hv) {
- pthread_mutex_unlock(&item_locks[hv & item_lock_mask]);
+ mutex_unlock(&item_locks[hv & item_lock_mask]);
}
/*
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
/*
* Processes an incoming "handle a new connection" item. This is called when
* input arrives on the libevent wakeup pipe.
void item_flush_expired() {
mutex_lock(&cache_lock);
do_item_flush_expired();
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
/*
mutex_lock(&cache_lock);
ret = do_item_cachedump(slabs_clsid, limit, bytes);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
return ret;
}
void item_stats(ADD_STAT add_stats, void *c) {
mutex_lock(&cache_lock);
do_item_stats(add_stats, c);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
/*
void item_stats_sizes(ADD_STAT add_stats, void *c) {
mutex_lock(&cache_lock);
do_item_stats_sizes(add_stats, c);
- pthread_mutex_unlock(&cache_lock);
+ mutex_unlock(&cache_lock);
}
/******************************* GLOBAL STATS ******************************/
}
}
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wsign-compare"
-#endif
/*
* Initializes the thread subsystem, creating various worker threads.
*
-#include "memcached.h"
+#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
+#include "memcached.h"
+
/* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */
#define xisspace(c) isspace((unsigned char)c)
+++ /dev/null
-m4_define([VERSION_NUMBER], [1.4.13])
%build
%configure
-%{__make}
+%{__make} %{?_smp_mflags}
%install
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
using namespace memcache;
using namespace libtest;
-Framework *global_framework= NULL;
+libtest::Framework *global_framework= NULL;
static test_return_t shutdown_servers(memcached_st *memc)
{
+ return TEST_SKIPPED;
+
test_skip_valgrind();
test_compare(memcached_server_count(memc), 1U);
static test_return_t add_shutdown_servers(memcached_st *memc)
{
+ return TEST_SKIPPED;
+
test_skip_valgrind();
while (memcached_server_count(memc) < 2)
#include "tests/libmemcached_world.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->servers().set_servers_to_run(1);
{0, 0, 0, 0}
};
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
}
return TEST_SUCCESS;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
#include <algorithm>
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
if (getenv("LIBMEMCACHED_SERVER_NUMBER"))
{
#include "tests/libmemcached_world_socket.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
#include "tests/libmemcached_world.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
{0, 0, 0, 0}
};
-void get_world(Framework *frame)
+void get_world(libtest::Framework* frame)
{
frame->collections(collection);
}
test_true(memc);
test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 2000000), MEMCACHED_SUCCESS);
+ test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 3000000), MEMCACHED_SUCCESS);
memcached_return_t rc;
#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#include "tests/libmemcached_world.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
#include "tests/libmemcached_world.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
{
if (server_startup(servers, "memcached-sasl", port, 0, NULL) == false)
{
+ error= TEST_SKIPPED;
+#if 0
fatal_message("Could not start memcached-sasl");
+#endif
+ return NULL;
}
}
else
{
if (server_startup(servers, "memcached", port, 0, NULL) == false)
{
+ error= TEST_SKIPPED;
+#if 0
fatal_message("Could not start memcached");
+#endif
+ return NULL;
}
}
}
const char *argv[1]= { "memcached" };
if (servers.start_socket_server("memcached", libtest::get_free_port(), 1, argv) == false)
{
+#if 0
fatal_message("Could not launch memcached");
+#endif
+ error= TEST_SKIPPED;
+ return NULL;
}
}
#include "tests/libmemcached_world.h"
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
if (server_startup(servers, "memcached", libtest::default_port(), 0, NULL) == false)
{
- error= TEST_FAILURE;
+ error= TEST_SKIPPED;
}
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
executable= "./clients/memcapable";
world->collections(collection);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
if (server_startup(servers, "memcached", libtest::default_port(), 0, NULL) == false)
{
- error= TEST_FAILURE;
+ error= TEST_SKIPPED;
}
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
if (server_startup(servers, "memcached", libtest::default_port(), 0, NULL) == 0)
{
- error= TEST_FAILURE;
+ error= TEST_SKIPPED;
}
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
executable= "./clients/memflush";
world->collections(collection);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
executable= "./clients/memslap";
world->collections(collection);
if (server_startup(servers, "memcached", libtest::default_port(), 0, NULL) == false)
{
- error= TEST_FAILURE;
+ error= TEST_SKIPPED;
}
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
world->create(world_create);
if (server_startup(servers, "memcached", libtest::default_port(), 0, NULL) == false)
{
- error= TEST_FAILURE;
+ error= TEST_SKIPPED;
}
return &servers;
}
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
executable= "./clients/memtouch";
world->collections(collection);
{0, 0, 0, 0}
};
-void get_world(Framework *world)
+void get_world(libtest::Framework* world)
{
world->collections(collection);
}