├── .gitignore ├── .gitmodules ├── .shipit ├── AUTHORS ├── COPYING ├── ChangeLog ├── Doxyfile ├── HACKING ├── LICENSE ├── Makefile.am ├── NEWS ├── README ├── TODO ├── TODO.moxi ├── agent.h ├── agent_config.c ├── agent_ping.c ├── agent_stats.c ├── assoc.c ├── assoc.h ├── cJSON.c ├── cJSON.h ├── cache.c ├── cache.h ├── check_moxi.c ├── check_moxi_agent.c ├── check_util.c ├── check_work.c ├── config ├── autorun.sh ├── config.rpath └── version.pl ├── config_static.h ├── configure.ac ├── cproxy.c ├── cproxy.h ├── cproxy_config.c ├── cproxy_front.c ├── cproxy_multiget.c ├── cproxy_protocol_a.c ├── cproxy_protocol_a2a.c ├── cproxy_protocol_a2b.c ├── cproxy_protocol_b.c ├── cproxy_protocol_b2b.c ├── cproxy_stats.c ├── daemon.c ├── debian ├── changelog.in ├── compat ├── control ├── copyright ├── dirs ├── docs ├── moxi.default ├── moxi.examples ├── moxi.init └── rules ├── devtools ├── bench_noreply.pl ├── clean-whitespace.pl └── svn-tarballs.pl ├── doc ├── CONTRIBUTORS ├── Doxyfile ├── Makefile.am ├── building-moxi-packages.txt ├── memory_management.txt ├── moxi.1 ├── moxi │ └── configuration.org ├── protocol.txt ├── readme.txt ├── threads.txt └── xml2rfc │ ├── reference.RFC.0768.xml │ ├── rfc2629-noinc.xsl │ ├── rfc2629-other.ent │ ├── rfc2629-refchk.xsl │ ├── rfc2629-xhtml.ent │ └── rfc2629.dtd ├── genhash.c ├── genhash.h ├── genhash_int.h ├── globals.c ├── hash.c ├── hash.h ├── htgram.c ├── htgram.h ├── htgram_test.c ├── items.c ├── items.h ├── log.c ├── log.h ├── m4 ├── ac_cxx_compile_stdcxx_0x.m4 ├── ac_cxx_header_stdcxx_98.m4 ├── acx_pthread.m4 ├── lib-ld.m4 ├── lib-link.m4 ├── lib-prefix.m4 ├── pandora_64bit.m4 ├── pandora_canonical.m4 ├── pandora_check_compiler_version.m4 ├── pandora_check_cxx_standard.m4 ├── pandora_enable_dtrace.m4 ├── pandora_ensure_gcc_version.m4 ├── pandora_extensions.m4 ├── pandora_have_better_malloc.m4 ├── pandora_have_innodb.m4 ├── pandora_have_libconflate.m4 ├── pandora_have_libdrizzle.m4 ├── pandora_have_libevent.m4 ├── pandora_have_libgearman.m4 ├── pandora_have_libhashkit.m4 ├── pandora_have_libmemcached.m4 ├── pandora_have_libpq.m4 ├── pandora_have_libsqlite3.m4 ├── pandora_have_libvbucket.m4 ├── pandora_have_protobuf.m4 ├── pandora_header_assert.m4 ├── pandora_libtool.m4 ├── pandora_optimize.m4 ├── pandora_platform.m4 ├── pandora_plugins.m4 ├── pandora_print_callstack.m4 ├── pandora_pthread.m4 ├── pandora_python3_devel.m4 ├── pandora_sasl.m4 ├── pandora_shared_ptr.m4 ├── pandora_swig.m4 ├── pandora_use_pipe.m4 ├── pandora_vc_build.m4 ├── pandora_warnings.m4 ├── pandora_with_lua.m4 ├── pandora_with_memcached.m4 ├── pandora_with_perl.m4 ├── pandora_with_php.m4 ├── pandora_with_python.m4 ├── pandora_with_python3.m4 ├── pandora_with_r.m4 ├── pandora_with_ruby.m4 └── pkg.m4 ├── matcher.c ├── matcher.h ├── mcs.c ├── mcs.h ├── memcached.c ├── memcached.h ├── memcached.spec.in ├── murmur_hash.c ├── protocol_binary.h ├── redirects.c ├── redirects.h ├── scripts ├── examples │ ├── moxi.conf.direct │ └── moxi.conf.service ├── memcached-init ├── memcached-tool ├── memcached.sysv ├── moxi-init.rhat.in ├── rpm │ ├── build-fc-rpm │ └── moxi.spec.in └── start-memcached ├── sizes.c ├── slabs.c ├── slabs.h ├── solaris_priv.c ├── stats.c ├── stats.h ├── stdin_check.c ├── stdin_check.h ├── t ├── 00-startup.t ├── 64bit.t ├── binary-get.t ├── binary.t ├── bogus-commands.t ├── cas.t ├── daemonize.t ├── dash-M.t ├── expirations.t ├── flags.t ├── flush-all.t ├── getset.t ├── incrdecr.t ├── issue_14.t ├── issue_22.t ├── issue_29.t ├── issue_41.t ├── issue_42.t ├── issue_50.t ├── issue_61.t ├── issue_70.t ├── lib │ └── MemcachedTest.pm ├── line-lengths.t ├── lru.t ├── maxconns.t ├── mc_bin_client.py ├── memcacheConstants.py ├── moxi.pl ├── moxi_all.pl ├── moxi_mock.cfg ├── moxi_mock.pl ├── moxi_mock_a2a.py ├── moxi_mock_a2b.py ├── moxi_mock_auth.py ├── moxi_mock_b2b.py ├── moxi_mock_server.py ├── moxi_multitenancy.py ├── moxi_multitenancy_default.py ├── moxi_multitenancy_rest.cfg ├── moxi_multitenancy_rest_default.cfg ├── moxi_one.pl ├── multiversioning.t ├── noreply.t ├── rest_mock.rb ├── slab-reassign.t ├── stats-detail.t ├── stats.t ├── stress-memcached.pl ├── udp.t ├── unixsocket.t ├── vbucket1.cfg ├── vbucket2.cfg ├── vbucket_rest1.cfg ├── vbucket_rest2.cfg └── whitespace.t ├── testapp.c ├── thread.c ├── timedrun.c ├── trace.h ├── util.c ├── util.h ├── version.sh ├── win32 └── win32.h ├── work.c └── work.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.[ao] 2 | *.exe 3 | *.gcda 4 | *.gcno 5 | *.gcov 6 | *.tcov 7 | *~ 8 | .buildbot/* 9 | .deps 10 | .libs 11 | /GPATH 12 | /GRTAGS 13 | /GSYMS 14 | /GTAGS 15 | /ID 16 | /check_moxi 17 | /check_moxi_agent 18 | /check_util 19 | /check_work 20 | /debian/changelog 21 | /doc/doxy 22 | /m4/version.m4 23 | /memcached.spec 24 | /scripts/rpm/moxi.spec 25 | /sizes 26 | /t/*.pyc 27 | /t/check_moxi_agent.cfg 28 | /testapp 29 | /timedrun 30 | /tmp 31 | /version.num 32 | INSTALL 33 | Makefile 34 | Makefile.in 35 | TAGS 36 | a.out* 37 | aclocal.m4 38 | autom4te.cache 39 | compile 40 | config.guess 41 | config.h 42 | config.h.in 43 | config.log 44 | config.status 45 | config.sub 46 | configure 47 | cscope.out 48 | depcomp 49 | doc/protocol-binary-range.txt 50 | doc/protocol-binary.txt 51 | htgram_test 52 | install-sh 53 | libmemcached-*/libmemcached/*.la 54 | libmemcached-*/libmemcached/*.lo 55 | libmemcached-*/libmemcached/.libs/ 56 | libmemcached-*/libmemcached/libmemcached_config.h 57 | libtool 58 | ltmain.sh 59 | m4/libtool.m4 60 | m4/ltoptions.m4 61 | m4/ltsugar.m4 62 | m4/ltversion.m4 63 | m4/lt~obsolete.m4 64 | memcached 65 | memcached-*.tar.gz 66 | memcached-debug 67 | memcached-debug.profile 68 | memcached_dtrace.h 69 | missing 70 | moxi 71 | moxi-*.tar.gz 72 | moxi-debug 73 | moxi-debug.profile 74 | moxi_*.tar.gz 75 | stamp-h1 76 | stamp-h2 77 | tags 78 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libconflate"] 2 | path = libconflate 3 | url = git://github.com/northscale/libconflate.git 4 | -------------------------------------------------------------------------------- /.shipit: -------------------------------------------------------------------------------- 1 | steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, AddToSVNDir 2 | 3 | AddToSVNDir.dir = ../website/dist 4 | svn.tagpattern = %v 5 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Anatoly Vorobey 2 | Brad Fitzpatrick 3 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003, Danga Interactive, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following disclaimer 13 | in the documentation and/or other materials provided with the 14 | distribution. 15 | 16 | * Neither the name of the Danga Interactive nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | * Hacking Moxi 2 | 3 | * Prerequisites 4 | 5 | - autoconf 6 | - automake 7 | - autotools 8 | - libevent 9 | - check 10 | 11 | * Getting Started 12 | 13 | After checking out a git repository, you must first run autogen.sh 14 | once in order to create the configure script. 15 | 16 | Next, run the configure script and start doing builds. 17 | 18 | * Setting up Git 19 | 20 | Though not required, there are a couple of things you can add to git 21 | to help development. 22 | 23 | ** Pre Commit Hook 24 | 25 | The pre-commit hook can be used to ensure that your tree passes tests 26 | before allowing a commit. To do so, add the following to 27 | .git/hooks/pre-commit (which must be executable): 28 | 29 | #!/bin/sh 30 | make test 31 | 32 | ** Post Commit Hook 33 | 34 | Because the version number changes on each commit, it's good to use a 35 | post commit hook to update the version number after each commit so as 36 | to keep the reporting accurate. To do so, add the following to 37 | .git/hooks/post-commit (which must be executable) 38 | 39 | #!/bin/sh 40 | ./version.sh 41 | 42 | * Running tests 43 | 44 | It has been noted that tests hang on some OSs. After investigation, 45 | this is due to those OSs using a default shell which doesn't kill off 46 | the child process from a kill. This has been noted on Ubuntu with 47 | the shell dash. To run tests convert the default shell to bash with 48 | dpkg-reconfigure. 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003, Danga Interactive, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following disclaimer 13 | in the documentation and/or other materials provided with the 14 | distribution. 15 | 16 | * Neither the name of the Danga Interactive nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | http://www.danga.com/memcached/news.bml 2 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * bug as shown with netcat (w/ small 16 byte object reproduces) 2 | 3 | >>I've done the following script to check that memcached has a key in it's 4 | >>inside, and thus know that it's working correctly: 5 | >>echo -e "get is_ok\r\nquit\r\n" | netcat $host $ip 6 | >> 7 | >>and I find that sometimes it returns the VALUE in it's inside, but other 8 | >>not. 9 | 10 | * namespaces 11 | 12 | * binary get protocol 13 | 14 | * refresh/touch command. 15 | 16 | * finer granularity of time for flush_all/delete, or generation number. 17 | 18 | * slab class reassignment still buggy and can crash. once that's 19 | stable, server should re-assign pages every 60 seconds or so 20 | to keep all classes roughly equal. [Update: fixed now?, but 21 | not heavily tested. Future: make slab classes, with per-class 22 | cleaners functions.] 23 | 24 | * calendar queue for early expirations of items, so they don't push 25 | out other objects with infinite expirations. 26 | 27 | * curr_items never decreases? mailing list report. 28 | 29 | * memcached to listen on more than one IP. mailing list request. 30 | -------------------------------------------------------------------------------- /agent.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | #ifndef AGENT_H 4 | #define AGENT_H 5 | 6 | #include 7 | #ifdef REDIRECTS_FOR_MOCKS 8 | #include "redirects.h" 9 | #endif 10 | 11 | int cproxy_init_agent(char *cfg_str, 12 | proxy_behavior behavior, 13 | int nthreads); 14 | 15 | proxy_main *cproxy_init_agent_start(char *jid, char *jpw, 16 | char *config, char *host, 17 | proxy_behavior behavior, 18 | int nthreads); 19 | 20 | void on_conflate_new_config(void *userdata, kvpair_t *config); 21 | enum conflate_mgmt_cb_result on_conflate_get_stats(void *opaque, 22 | conflate_handle_t *handle, 23 | const char *cmd, 24 | bool direct, 25 | kvpair_t *form, 26 | conflate_form_result *); 27 | enum conflate_mgmt_cb_result on_conflate_reset_stats(void *opaque, 28 | conflate_handle_t *handle, 29 | const char *cmd, 30 | bool direct, 31 | kvpair_t *form, 32 | conflate_form_result *); 33 | enum conflate_mgmt_cb_result on_conflate_ping_test(void *opaque, 34 | conflate_handle_t *handle, 35 | const char *cmd, 36 | bool direct, 37 | kvpair_t *form, 38 | conflate_form_result *); 39 | 40 | void cproxy_on_config_pool(proxy_main *m, 41 | char *name, int port, 42 | char *config_str, 43 | uint32_t config_ver, 44 | proxy_behavior_pool *behavior_pool); 45 | 46 | char **get_key_values(kvpair_t *kvs, char *key); 47 | 48 | void proxy_stats_dump_basic(ADD_STAT add_stats, conn *c, 49 | const char *prefix); 50 | void proxy_stats_dump_proxy_main(ADD_STAT add_stats, conn *c, 51 | struct proxy_stats_cmd_info *pscip); 52 | void proxy_stats_dump_proxies(ADD_STAT add_stats, conn *c, 53 | struct proxy_stats_cmd_info *pscip); 54 | void proxy_stats_dump_timings(ADD_STAT add_stats, conn *c); 55 | 56 | #endif /* AGENT_H */ 57 | -------------------------------------------------------------------------------- /assoc.h: -------------------------------------------------------------------------------- 1 | /* associative array */ 2 | void assoc_init(void); 3 | item *assoc_find(const char *key, const size_t nkey); 4 | int assoc_insert(item *item); 5 | void assoc_delete(const char *key, const size_t nkey); 6 | void do_assoc_move_next_bucket(void); 7 | int start_assoc_maintenance_thread(void); 8 | void stop_assoc_maintenance_thread(void); 9 | 10 | -------------------------------------------------------------------------------- /check_work.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "memcached.h" 11 | #include "cproxy.h" 12 | #include "work.h" 13 | 14 | struct agg { 15 | pthread_mutex_t lock; 16 | int visits; 17 | }; 18 | 19 | int main_check(int argc, char **argv); 20 | 21 | static void test_collect_worker(void *data0, void *data1) { 22 | fail_unless(data0 != NULL, "wsc"); 23 | fail_unless(data1 != NULL, "wsc"); 24 | fail_unless(data0 == data1, "wsc"); 25 | 26 | work_collect *c = data0; 27 | struct agg *agg = c->data; 28 | 29 | fail_unless(agg != NULL, "agg"); 30 | 31 | pthread_mutex_lock(&agg->lock); 32 | agg->visits++; 33 | pthread_mutex_unlock(&agg->lock); 34 | 35 | work_collect_one(c); 36 | } 37 | 38 | static void test_collect_main(void) { 39 | int nthreads = settings.num_threads; 40 | 41 | struct agg agg; 42 | 43 | pthread_mutex_init(&agg.lock, NULL); 44 | 45 | agg.visits = 0; 46 | 47 | work_collect c; 48 | work_collect_init(&c, nthreads - 1, &agg); 49 | 50 | for (int i = 1; i < nthreads; i++) { 51 | LIBEVENT_THREAD *t = thread_by_index(i); 52 | fail_unless(NULL != t, "tc"); 53 | fail_unless(NULL != t->work_queue, "tc"); 54 | work_send(t->work_queue, test_collect_worker, &c, &c); 55 | } 56 | 57 | work_collect_wait(&c); 58 | 59 | fail_unless(agg.visits == nthreads - 1, "collect"); 60 | } 61 | 62 | START_TEST(test_collect) 63 | { 64 | test_collect_main(); 65 | } 66 | END_TEST 67 | 68 | static void test_one_worker(void *data0, void *data1) { 69 | char *s0 = data0; 70 | char *s1 = data1; 71 | 72 | fail_unless(strcmp(s0, "hello") == 0, "tcw"); 73 | fail_unless(strcmp(s1, "world") == 0, "tcw"); 74 | } 75 | 76 | START_TEST(test_one) 77 | { 78 | LIBEVENT_THREAD *t = thread_by_index(1); 79 | fail_unless(NULL != t, "tc"); 80 | fail_unless(NULL != t->work_queue, "tc"); 81 | work_send(t->work_queue, test_one_worker, "hello", "world"); 82 | sleep(1); 83 | } 84 | END_TEST 85 | 86 | static 87 | void setup(void) 88 | { 89 | start_main("moxi", NULL); 90 | } 91 | 92 | static Suite* work_suite(void) 93 | { 94 | Suite *s = suite_create("work"); 95 | 96 | /* Core test case */ 97 | TCase *tc_core = tcase_create("core"); 98 | tcase_add_checked_fixture(tc_core, setup, NULL); 99 | tcase_add_test(tc_core, test_one); 100 | tcase_add_test(tc_core, test_collect); 101 | suite_add_tcase(s, tc_core); 102 | 103 | return s; 104 | } 105 | 106 | /** 107 | * Run this like... 108 | * check_work -vvv -p 11211 109 | */ 110 | int main(int argc, char **argv) 111 | { 112 | int number_failed; 113 | Suite *s = work_suite(); 114 | SRunner *sr = srunner_create(s); 115 | srunner_run_all(sr, CK_ENV); 116 | number_failed = srunner_ntests_failed(sr); 117 | srunner_free(sr); 118 | 119 | return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 120 | } 121 | -------------------------------------------------------------------------------- /config/autorun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | LIBTOOLIZE_FLAGS="--automake --copy --force" 4 | AUTOMAKE_FLAGS="--add-missing --copy --force --foreign --warning=portability" 5 | ACLOCAL_FLAGS="-I m4" 6 | AUTOHEADER_FLAGS="--warnings=error" 7 | AUTOCONF_CLAGS="--warnings=error --force" 8 | 9 | 10 | ARGV0=$0 11 | ARGS="$@" 12 | 13 | die() { echo "$@"; exit 1; } 14 | 15 | run() { 16 | echo "$ARGV0: running \`$@' $ARGS" 17 | $@ $ARGS 18 | } 19 | 20 | # Try to locate a program by using which, and verify that the file is an 21 | # executable 22 | locate_binary() { 23 | for f in $@ 24 | do 25 | file=`which $f 2>/dev/null | grep -v '^no '` 26 | if test -n "$file" -a -x "$file"; then 27 | echo $file 28 | return 0 29 | fi 30 | done 31 | 32 | echo "" 33 | return 1 34 | } 35 | 36 | if test -f config/pre_hook.sh 37 | then 38 | . config/pre_hook.sh 39 | fi 40 | 41 | if [ -d .git ] 42 | then 43 | perl config/version.pl || die "Failed to run config/version.pl" 44 | fi 45 | 46 | # Try to detect the supported binaries if the user didn't 47 | # override that by pushing the environment variable 48 | if test x$LIBTOOLIZE = x; then 49 | LIBTOOLIZE=`locate_binary libtoolize glibtoolize` 50 | if test x$LIBTOOLIZE = x; then 51 | die "Did not find a supported libtoolize" 52 | fi 53 | fi 54 | 55 | if test x$ACLOCAL = x; then 56 | ACLOCAL=`locate_binary aclocal-1.11 aclocal-1.10 aclocal` 57 | if test x$ACLOCAL = x; then 58 | die "Did not find a supported aclocal" 59 | fi 60 | fi 61 | 62 | if test x$AUTOMAKE = x; then 63 | AUTOMAKE=`locate_binary automake-1.11 automake-1.10 automake` 64 | if test x$AUTOMAKE = x; then 65 | die "Did not find a supported automake" 66 | fi 67 | fi 68 | 69 | if test x$AUTOCONF = x; then 70 | AUTOCONF=`locate_binary autoconf` 71 | if test x$AUTOCONF = x; then 72 | die "Did not find a supported autoconf" 73 | fi 74 | fi 75 | 76 | if test x$AUTOHEADER = x; then 77 | AUTOHEADER=`locate_binary autoheader` 78 | if test x$AUTOHEADER = x; then 79 | die "Did not find a supported autoheader" 80 | fi 81 | fi 82 | 83 | run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize" 84 | run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal" 85 | run $AUTOHEADER $AUTOHEADER_FLAGS || die "Can't execute autoheader" 86 | run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake" 87 | run $AUTOCONF $AUTOCONF_FLAGS || die "Can't execute autoconf" 88 | 89 | if test -f config/post_hook.sh 90 | then 91 | . config/post_hook.sh 92 | fi 93 | 94 | echo "---" 95 | echo "Configured with the following tools:" 96 | echo " * `$LIBTOOLIZE --version | head -1`" 97 | echo " * `$ACLOCAL --version | head -1`" 98 | echo " * `$AUTOHEADER --version | head -1`" 99 | echo " * `$AUTOMAKE --version | head -1`" 100 | echo " * `$AUTOCONF --version | head -1`" 101 | echo "---" 102 | -------------------------------------------------------------------------------- /config/version.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # If you think this is stupid/overkill, blame dormando 3 | 4 | use warnings; 5 | use strict; 6 | 7 | my $version = `git describe`; 8 | chomp $version; 9 | # Test the various versions. 10 | #my $version = 'foob'; 11 | #my $version = '1.4.2-30-gf966dba'; 12 | #my $version = '1.4.3-rc1'; 13 | #my $version = '1.4.3'; 14 | unless ($version =~ m/^\d+\.\d+\.\d+/) { 15 | write_file('m4/version.m4', "m4_define([VERSION_NUMBER], [UNKNOWN])\n"); 16 | exit; 17 | } 18 | 19 | $version =~ s/-/_/g; 20 | write_file('m4/version.m4', "m4_define([VERSION_NUMBER], [$version])\n"); 21 | my ($VERSION, $FULLVERSION, $RELEASE); 22 | 23 | if ($version =~ m/^(\d+\.\d+\.\d+)_rc(\d+)$/) { 24 | $VERSION = $1; 25 | $FULLVERSION = $version; 26 | $RELEASE = '0.1.rc' . $2; 27 | } elsif ($version =~ m/^(\d+\.\d+\.\d+)_(.+)$/) { 28 | $VERSION = $1; 29 | $FULLVERSION = $version; 30 | $RELEASE = '1.' . $2; 31 | } elsif ($version =~ m/^(\d+\.\d+\.\d+)$/) { 32 | $VERSION = $1; 33 | $FULLVERSION = $version; 34 | $RELEASE = '1'; 35 | } 36 | 37 | sub write_file { 38 | my $file = shift; 39 | my $data = shift; 40 | open(my $fh, "> $file") or die "Can't open $file: $!"; 41 | print $fh $data; 42 | close($fh); 43 | } 44 | 45 | sub read_file { 46 | my $file = shift; 47 | local $/ = undef; 48 | open(my $fh, "< $file") or die "Can't open $file: $!"; 49 | my $data = <$fh>; 50 | close($fh); 51 | return $data; 52 | } 53 | -------------------------------------------------------------------------------- /config_static.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | /* 3 | * Copyright 2010 NorthScale, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef CONFIG_STATIC_H 18 | #define CONFIG_STATIC_H 1 19 | 20 | // The intention of this file is to avoid cluttering the code with #ifdefs 21 | 22 | #ifdef WIN32 23 | // HAVE_CONFIG_H is causing problems with pthreads.h on in32 24 | #undef HAVE_CONFIG_H 25 | 26 | #define _WIN32_WINNT 0x0501 27 | #include 28 | #include 29 | 30 | struct iovec { 31 | size_t iov_len; 32 | void* iov_base; 33 | }; 34 | 35 | #include "win32/win32.h" 36 | 37 | #define EX_USAGE EXIT_FAILURE 38 | #define EX_OSERR EXIT_FAILURE 39 | 40 | #else 41 | #define initialize_sockets() 42 | #endif 43 | 44 | #ifdef HAVE_SYS_SOCKET_H 45 | #include 46 | #endif 47 | 48 | #ifdef HAVE_NETDB_H 49 | #include 50 | #endif 51 | 52 | #ifdef HAVE_ARPA_INET_H 53 | #include 54 | #endif 55 | 56 | #ifdef HAVE_PWD_H 57 | #include 58 | #endif 59 | 60 | #ifdef HAVE_SYS_MMAN_H 61 | #include 62 | #endif 63 | 64 | #ifdef HAVE_NETINET_TCP_H 65 | #include 66 | #endif 67 | 68 | #ifdef HAVE_SYSEXITS_H 69 | #include 70 | #endif 71 | 72 | #ifdef HAVE_SYS_UIO_H 73 | #include 74 | #endif 75 | 76 | #ifdef HAVE_SYS_UN_H 77 | #include 78 | #endif 79 | 80 | #ifdef HAVE_SYS_RESOURCE_H 81 | #include 82 | #endif 83 | 84 | #ifdef HAVE_NETINET_IN_H 85 | #include 86 | #endif 87 | 88 | #ifdef HAVE_SYSLOG_H 89 | #include 90 | #endif 91 | 92 | #ifndef DEFAULT_ERRORLOG 93 | #define DEFAULT_ERRORLOG ERRORLOG_STDERR 94 | #endif 95 | 96 | #if defined(WORDS_BIGENDIAN) && WORDS_BIGENDIAN > 1 97 | #define ENDIAN_BIG 1 98 | #else 99 | #define ENDIAN_LITTLE 1 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /daemon.c: -------------------------------------------------------------------------------- 1 | /* $Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $ */ 2 | /* $NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $ */ 3 | /*- 4 | * Copyright (c) 1990, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #if defined __SUNPRO_C || defined __DECC || defined __HP_cc 33 | # pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $" 34 | # pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $" 35 | #endif 36 | 37 | #include "config.h" 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "memcached.h" 44 | 45 | int daemonize(int nochdir, int noclose) 46 | { 47 | int fd; 48 | 49 | switch (fork()) { 50 | case -1: 51 | return (-1); 52 | case 0: 53 | break; 54 | default: 55 | _exit(EXIT_SUCCESS); 56 | } 57 | 58 | if (setsid() == -1) 59 | return (-1); 60 | 61 | if (nochdir == 0) { 62 | if(chdir("/") != 0) { 63 | perror("chdir"); 64 | return (-1); 65 | } 66 | } 67 | 68 | if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) { 69 | if(dup2(fd, STDIN_FILENO) < 0) { 70 | perror("dup2 stdin"); 71 | return (-1); 72 | } 73 | if(dup2(fd, STDOUT_FILENO) < 0) { 74 | perror("dup2 stdout"); 75 | return (-1); 76 | } 77 | if(dup2(fd, STDERR_FILENO) < 0) { 78 | perror("dup2 stderr"); 79 | return (-1); 80 | } 81 | 82 | if (fd > STDERR_FILENO) { 83 | if(close(fd) < 0) { 84 | perror("close"); 85 | return (-1); 86 | } 87 | } 88 | } 89 | return (0); 90 | } 91 | -------------------------------------------------------------------------------- /debian/changelog.in: -------------------------------------------------------------------------------- 1 | moxi (@VERSION@-1) unstable; urgency=low 2 | 3 | * Packaged @VERSION@ 4 | 5 | -- Northscale @DATE@ 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: moxi 2 | Section: web 3 | Priority: optional 4 | Maintainer: Northscale 5 | Build-Depends: debhelper (>= 5), libevent-dev, check, libsqlite3-dev, libssl-dev, pkg-config, automake, libtool, git-core 6 | Standards-Version: 3.8.1 7 | Homepage: http://labs.northscale.com/moxi 8 | 9 | Package: moxi 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base (>= 3.2) 12 | Description: a high performance, multithreaded memcached proxy 13 | moxi is a high performance memcached proxy with several optimizations 14 | which may be useful when deploying memcached at a large scale or in 15 | cloud compute environments. moxi was produced by NorthScale and is 16 | Open Source under the BSD license. 17 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Moxi is based on code of memcached (http://www.danga.com/memcached/) and is 2 | licensed under same license -- BSD. 3 | 4 | On Debian systems, the complete text of the BSD License can be 5 | found in `/usr/share/common-licenses/BSD'. 6 | -------------------------------------------------------------------------------- /debian/dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | AUTHORS 3 | COPYING 4 | doc/CONTRIBUTORS 5 | scripts/examples/ 6 | -------------------------------------------------------------------------------- /debian/moxi.default: -------------------------------------------------------------------------------- 1 | # Defaults for moxi initscript 2 | # sourced by /etc/init.d/moxi 3 | # installed at /etc/default/moxi by the maintainer scripts 4 | 5 | # 6 | # This is a POSIX shell fragment 7 | # 8 | 9 | # uncomment to enable moxi 10 | #RUN="yes" 11 | MAXCONN=1024 12 | PIDFILE=/var/run/moxi/moxi.pid 13 | PROXY_ARG="-z /etc/moxi.conf" 14 | # Additional options that are passed to the Daemon. 15 | DAEMON_OPTS="-u nobody -d -c $MAXCONN $PROXY_ARG -P $PIDFILE" 16 | -------------------------------------------------------------------------------- /debian/moxi.examples: -------------------------------------------------------------------------------- 1 | scripts/examples/* 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | 14 | 15 | 16 | configure: configure-stamp 17 | configure-stamp: 18 | dh_testdir 19 | 20 | CONFLATE_DB_PATH=/var/lib/moxi ./configure --prefix=/usr --disable-coverage --disable-debug --disable-shared --without-memcached --with-bundled-libstrophe --with-libconflate=bundled 21 | 22 | touch configure-stamp 23 | 24 | 25 | build: build-stamp 26 | 27 | build-stamp: configure-stamp 28 | dh_testdir 29 | $(MAKE) 30 | 31 | touch $@ 32 | 33 | clean: 34 | dh_testdir 35 | dh_testroot 36 | rm -f build-stamp configure-stamp 37 | 38 | -$(MAKE) distclean 39 | 40 | dh_clean 41 | 42 | install: build 43 | dh_testdir 44 | dh_testroot 45 | -dh_prep 46 | dh_installdirs 47 | 48 | mkdir -p $(CURDIR)/debian/moxi/var/run/moxi 49 | chown nobody:nogroup -R $(CURDIR)/debian/moxi/var/run/moxi 50 | 51 | $(MAKE) DESTDIR=$(CURDIR)/debian/moxi install 52 | 53 | # we don't need headers and static libs from conflate & strophe 54 | rm -rf $(CURDIR)/debian/moxi/usr/lib 55 | rm -rf $(CURDIR)/debian/moxi/usr/include 56 | 57 | mkdir -p $(CURDIR)/debian/moxi/var/lib/moxi 58 | chown nobody:nogroup -R $(CURDIR)/debian/moxi/var/lib/moxi 59 | 60 | # Build architecture-independent files here. 61 | binary-indep: install 62 | # We have nothing to do by default. 63 | 64 | # Build architecture-dependent files here. 65 | binary-arch: install 66 | dh_testdir 67 | dh_testroot 68 | dh_installchangelogs 69 | dh_installdocs 70 | dh_installexamples 71 | # dh_install 72 | # dh_installmenu 73 | # dh_installdebconf 74 | # dh_installlogrotate 75 | # dh_installemacsen 76 | # dh_installpam 77 | # dh_installmime 78 | # dh_python 79 | dh_installinit 80 | # dh_installcron 81 | # dh_installinfo 82 | dh_installman 83 | dh_link 84 | dh_strip 85 | dh_compress 86 | dh_fixperms -Xvar/run/moxi -Xvar/lib/moxi 87 | # dh_perl 88 | # dh_makeshlibs 89 | dh_installdeb 90 | dh_shlibdeps 91 | dh_gencontrol 92 | dh_md5sums 93 | dh_builddeb 94 | 95 | binary: binary-indep binary-arch 96 | .PHONY: build clean binary-indep binary-arch binary install configure 97 | -------------------------------------------------------------------------------- /devtools/bench_noreply.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | # 3 | use warnings; 4 | use strict; 5 | 6 | use IO::Socket::INET; 7 | 8 | use FindBin; 9 | 10 | @ARGV == 1 or @ARGV == 2 11 | or die "Usage: $FindBin::Script HOST:PORT [COUNT]\n"; 12 | 13 | # Note that it's better to run the test over the wire, because for 14 | # localhost the task may become CPU bound. 15 | my $addr = $ARGV[0]; 16 | my $count = $ARGV[1] || 10_000; 17 | 18 | my $sock = IO::Socket::INET->new(PeerAddr => $addr, 19 | Timeout => 3); 20 | die "$!\n" unless $sock; 21 | 22 | 23 | # By running 'noreply' test first we also ensure there are no reply 24 | # packets left in the network. 25 | foreach my $noreply (1, 0) { 26 | use Time::HiRes qw(gettimeofday tv_interval); 27 | 28 | print "'noreply' is ", $noreply ? "enabled" : "disabled", ":\n"; 29 | my $param = $noreply ? 'noreply' : ''; 30 | my $start = [gettimeofday]; 31 | foreach (1 .. $count) { 32 | print $sock "add foo 0 0 1 $param\r\n1\r\n"; 33 | scalar<$sock> unless $noreply; 34 | print $sock "set foo 0 0 1 $param\r\n1\r\n"; 35 | scalar<$sock> unless $noreply; 36 | print $sock "replace foo 0 0 1 $param\r\n1\r\n"; 37 | scalar<$sock> unless $noreply; 38 | print $sock "append foo 0 0 1 $param\r\n1\r\n"; 39 | scalar<$sock> unless $noreply; 40 | print $sock "prepend foo 0 0 1 $param\r\n1\r\n"; 41 | scalar<$sock> unless $noreply; 42 | print $sock "incr foo 1 $param\r\n"; 43 | scalar<$sock> unless $noreply; 44 | print $sock "decr foo 1 $param\r\n"; 45 | scalar<$sock> unless $noreply; 46 | print $sock "delete foo $param\r\n"; 47 | scalar<$sock> unless $noreply; 48 | } 49 | my $end = [gettimeofday]; 50 | printf("update commands: %.2f secs\n\n", tv_interval($start, $end)); 51 | } 52 | -------------------------------------------------------------------------------- /devtools/clean-whitespace.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use FindBin qw($Bin); 4 | chdir "$Bin/.." or die; 5 | my @files = (glob("*.h"), glob("*.c"), glob("*.ac")); 6 | foreach my $f (@files) { 7 | open(my $fh, $f) or die; 8 | my $before = do { local $/; <$fh>; }; 9 | close ($fh); 10 | my $after = $before; 11 | $after =~ s/\t/ /g; 12 | $after =~ s/ +$//mg; 13 | $after .= "\n" unless $after =~ /\n$/; 14 | next if $after eq $before; 15 | open(my $fh, ">$f") or die; 16 | print $fh $after; 17 | close($fh); 18 | } 19 | -------------------------------------------------------------------------------- /devtools/svn-tarballs.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use FindBin qw($Bin); 5 | 6 | my %branch = ( 7 | '1.2.x' => "http://code.sixapart.com/svn/memcached/trunk/server", 8 | '1.1.x' => "http://code.sixapart.com/svn/memcached/branches/memcached-1.1.x", 9 | ); 10 | 11 | foreach my $b (keys %branch) { 12 | chdir $Bin or die; 13 | my $url = $branch{$b}; 14 | my $out = `svn info $b`; 15 | unless ($out =~ /^URL: (.+)/m && $1 eq $url) { 16 | system("rm -rf $b"); 17 | system("svn", "co", $url, $b) 18 | and die "Failed to checkout $url\n"; 19 | } else { 20 | chdir "$Bin/$b" or die; 21 | system("svn up") and die "Failed to svn up"; 22 | } 23 | 24 | chdir "$Bin/$b" or die; 25 | $out = `svn info .`; 26 | 27 | my ($maxrev) = $out =~ /^Last Changed Rev: (\d+)/m 28 | or die "No max rev?"; 29 | 30 | print "$b = $maxrev\n"; 31 | my $distfile = "memcached-$b-svn$maxrev.tar.gz"; 32 | next if -f $distfile && -s _; 33 | 34 | open(my $fh, "configure.ac") or die "no configure.ac in $b?"; 35 | my $ac = do { local $/; <$fh>; }; 36 | close($fh); 37 | $ac =~ s!AC_INIT\(memcached,.+?\)!AC_INIT(memcached, $b-svn$maxrev, brad\@danga.com)! 38 | or die "Failed to replace"; 39 | open (my $fh, ">configure.ac") or die "failed to write configure.ac writeable: $!"; 40 | print $fh $ac; 41 | close ($fh); 42 | 43 | system("./autogen.sh") and die "Autogen failed. Missing autotools?"; 44 | system("./configure") and die "configure failed"; 45 | system("make dist") and die "make dist failed"; 46 | die "Failed to make dist $distfile." unless -s $distfile; 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /doc/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | MEMCACHED CONTRIBUTORS 2 | 3 | This file contains a list of people who have contributed code and 4 | effort to the memcached project. If you don't see your name mentioned 5 | send email to the memcached mailing list so you can be immortalized. 6 | 7 | Also see the ChangeLog for even more people who have helped over the 8 | years by submitting fixes, patches and reporting bugs. 9 | 10 | 11 | Major authors: 12 | -------------- 13 | 14 | Brad Fitzpatrick -- maintainer, original implementations 15 | 16 | Anatoly Vorobey -- lots of the modern server code 17 | 18 | Steven Grimm -- iov writing (less CPU), UDP mode, 19 | non-2.0 slab mantissas, multithread, ... 20 | 21 | Other Contributors 22 | ------------------ 23 | 24 | Evan Martin 25 | Nathan Neulinger 26 | Eric Hodel 27 | Michael Johnson 28 | Paul Querna 29 | Jamie McCarthy 30 | Philip Neustrom 31 | Andrew O'Brien 32 | Josh Rotenberg 33 | Robin H. Johnson 34 | Tim Yardley 35 | Paolo Borelli 36 | Eli Bingham 37 | Jean-Francois Bustarret 38 | Paul G 39 | Paul Lindner 40 | Dormando 41 | Dustin Sallings 42 | Chris Goffinet 43 | Tomash Brechko 44 | Brian Aker 45 | Trond Norbye 46 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | man_MANS = moxi.1 2 | 3 | EXTRA_DIST = *.txt 4 | 5 | BUILT_SOURCES= 6 | -------------------------------------------------------------------------------- /doc/building-moxi-packages.txt: -------------------------------------------------------------------------------- 1 | For Fedora 2 | ---------- 3 | 4 | First setup your build environment as pointed out in 5 | http://fedoraproject.org/wiki/How_to_create_an_RPM_package 6 | 7 | $ rpmdev-setuptree 8 | 9 | Then 10 | 11 | $ ./autogen.sh && ./configure --with-libconflate=bundled \ 12 | --with-bundled-libstrophe && make fc_rpm 13 | 14 | this will produce source and binary rpms for your architecture. 15 | 16 | For Debian/Ubuntu 17 | ----------------- 18 | 19 | $ ./autogen.sh && ./configure --with-libconflate=bundled \ 20 | --with-bundled-libstrophe && make dist 21 | 22 | Than unpack moxi .tar.gz source archive and inside source directory 23 | run 24 | 25 | $ dpkg-buildpackage 26 | -------------------------------------------------------------------------------- /doc/readme.txt: -------------------------------------------------------------------------------- 1 | To build the documentation you need xml2rfc ( http://xml.resource.org/ ). 2 | -------------------------------------------------------------------------------- /doc/threads.txt: -------------------------------------------------------------------------------- 1 | Multithreading support in memcached 2 | 3 | OVERVIEW 4 | 5 | By default, memcached is compiled as a single-threaded application. This is 6 | the most CPU-efficient mode of operation, and it is appropriate for memcached 7 | instances running on single-processor servers or whose request volume is 8 | low enough that available CPU power is not a bottleneck. 9 | 10 | More heavily-used memcached instances can benefit from multithreaded mode. 11 | To enable it, use the "--enable-threads" option to the configure script: 12 | 13 | ./configure --enable-threads 14 | 15 | You must have the POSIX thread functions (pthread_*) on your system in order 16 | to use memcached's multithreaded mode. 17 | 18 | Once you have a thread-capable memcached executable, you can control the 19 | number of threads using the "-t" option; the default is 4. On a machine 20 | that's dedicated to memcached, you will typically want one thread per 21 | processor core. Due to memcached's nonblocking architecture, there is no 22 | real advantage to using more threads than the number of CPUs on the machine; 23 | doing so will increase lock contention and is likely to degrade performance. 24 | 25 | 26 | INTERNALS 27 | 28 | The threading support is mostly implemented as a series of wrapper functions 29 | that protect calls to underlying code with one of a small number of locks. 30 | In single-threaded mode, the wrappers are replaced with direct invocations 31 | of the target code using #define; that is done in memcached.h. This approach 32 | allows memcached to be compiled in either single- or multi-threaded mode. 33 | 34 | Each thread has its own instance of libevent ("base" in libevent terminology). 35 | The only direct interaction between threads is for new connections. One of 36 | the threads handles the TCP listen socket; each new connection is passed to 37 | a different thread on a round-robin basis. After that, each thread operates 38 | on its set of connections as if it were running in single-threaded mode, 39 | using libevent to manage nonblocking I/O as usual. 40 | 41 | UDP requests are a bit different, since there is only one UDP socket that's 42 | shared by all clients. The UDP socket is monitored by all of the threads. 43 | When a datagram comes in, all the threads that aren't already processing 44 | another request will receive "socket readable" callbacks from libevent. 45 | Only one thread will successfully read the request; the others will go back 46 | to sleep or, in the case of a very busy server, will read whatever other 47 | UDP requests are waiting in the socket buffer. Note that in the case of 48 | moderately busy servers, this results in increased CPU consumption since 49 | threads will constantly wake up and find no input waiting for them. But 50 | short of much more major surgery on the I/O code, this is not easy to avoid. 51 | 52 | 53 | TO DO 54 | 55 | The locking is currently very coarse-grained. There is, for example, one 56 | lock that protects all the calls to the hashtable-related functions. Since 57 | memcached spends much of its CPU time on command parsing and response 58 | assembly, rather than managing the hashtable per se, this is not a huge 59 | bottleneck for small numbers of processors. However, the locking will likely 60 | have to be refined in the event that memcached needs to run well on 61 | massively-parallel machines. 62 | 63 | One cheap optimization to reduce contention on that lock: move the hash value 64 | computation so it occurs before the lock is obtained whenever possible. 65 | Right now the hash is performed at the lowest levels of the functions in 66 | assoc.c. If instead it was computed in memcached.c, then passed along with 67 | the key and length into the items.c code and down into assoc.c, that would 68 | reduce the amount of time each thread needs to keep the hashtable lock held. 69 | -------------------------------------------------------------------------------- /doc/xml2rfc/reference.RFC.0768.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | User Datagram Protocol 7 | 8 | University of Southern California (USC)/Information Sciences Institute 9 |
10 | 11 | 4676 Admiralty Way 12 | Marina del Rey 13 | CA 14 | 90291 15 | US 16 | +1 213 822 1511
17 |
18 | 19 | 20 | 21 | 22 |
23 | -------------------------------------------------------------------------------- /doc/xml2rfc/rfc2629-noinc.xsl: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | .xml 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | http://xml.resource.org/public/rfc/ 51 | 52 | .xml 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /doc/xml2rfc/rfc2629-other.ent: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /doc/xml2rfc/rfc2629-refchk.xsl: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /genhash_int.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \private 3 | */ 4 | struct genhash_entry_t { 5 | /** The key for this entry */ 6 | void *key; 7 | /** The value for this entry */ 8 | void *value; 9 | /** Pointer to the next entry */ 10 | struct genhash_entry_t *next; 11 | }; 12 | 13 | struct _genhash { 14 | size_t size; 15 | struct hash_ops ops; 16 | struct genhash_entry_t *buckets[]; 17 | }; 18 | -------------------------------------------------------------------------------- /globals.c: -------------------------------------------------------------------------------- 1 | #include "memcached.h" 2 | 3 | /* 4 | * This file contains global variables shared across the rest of the 5 | * memcached codebase. These were originally in memcached.c but had 6 | * to be removed to make the rest of the object files linkable into 7 | * the test infrastructure. 8 | * 9 | */ 10 | 11 | /* 12 | * We keep the current time of day in a global variable that's updated by a 13 | * timer event. This saves us a bunch of time() system calls (we really only 14 | * need to get the time once a second, whereas there can be tens of thousands 15 | * of requests a second) and allows us to use server-start-relative timestamps 16 | * rather than absolute UNIX timestamps, a space savings on systems where 17 | * sizeof(time_t) > sizeof(unsigned int). 18 | */ 19 | volatile rel_time_t current_time; 20 | 21 | /** exported globals **/ 22 | struct stats stats; 23 | struct settings settings; 24 | -------------------------------------------------------------------------------- /hash.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_H 2 | #define HASH_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | uint32_t hash(const void *key, size_t length, const uint32_t initval); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* HASH_H */ 15 | 16 | -------------------------------------------------------------------------------- /items.h: -------------------------------------------------------------------------------- 1 | /* See items.c */ 2 | void item_init(void); 3 | uint64_t get_cas_id(void); 4 | 5 | /*@null@*/ 6 | item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes); 7 | void item_free(item *it); 8 | bool item_size_ok(const size_t nkey, const int flags, const int nbytes); 9 | 10 | int do_item_link(item *it); /** may fail if transgresses limits */ 11 | void do_item_unlink(item *it); 12 | void do_item_remove(item *it); 13 | void do_item_update(item *it); /** update LRU time to current and reposition */ 14 | int do_item_replace(item *it, item *new_it); 15 | 16 | /*@null@*/ 17 | char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); 18 | void do_item_stats(ADD_STAT add_stats, void *c); 19 | /*@null@*/ 20 | void do_item_stats_sizes(ADD_STAT add_stats, void *c); 21 | void do_item_flush_expired(void); 22 | 23 | item *do_item_get(const char *key, const size_t nkey); 24 | item *do_item_get_nocheck(const char *key, const size_t nkey); 25 | void item_stats_reset(void); 26 | extern pthread_mutex_t cache_lock; 27 | -------------------------------------------------------------------------------- /log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * moxi logging API 3 | * mtaneja@zynga.com 4 | */ 5 | 6 | #ifndef _LOG_H_ 7 | #define _LOG_H_ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * define the log levels 14 | */ 15 | 16 | #define MOXI_LOG_CRIT 1 17 | #define MOXI_LOG_ERR 5 18 | #define MOXI_LOG_INFO 10 19 | #define MOXI_LOG_DEBUG 15 20 | 21 | 22 | #define ERRORLOG_STDERR 0x1 23 | #define ERRORLOG_FILE 0x2 24 | #define ERRORLOG_SYSLOG 0x4 25 | 26 | 27 | struct moxi_log { 28 | 29 | int fd; /* log fd */ 30 | int log_level; /* logging level. default 5 */ 31 | int log_mode; /* syslog, log file, stderr */ 32 | char *log_ident; /* syslog identifier */ 33 | char *log_file; /* if log file is specified */ 34 | int use_syslog; /* set if syslog is being used */ 35 | char *logbuf; /* scratch buffer */ 36 | int logbuf_used; /* length of scratch buffer */ 37 | time_t cur_ts; /* current timestamp */ 38 | time_t last_generated_debug_ts; 39 | }; 40 | 41 | typedef struct moxi_log moxi_log; 42 | 43 | int log_error_open(moxi_log *); 44 | int log_error_close(moxi_log *); 45 | int log_error_write(moxi_log *, const char *filename, unsigned int line, const char *fmt, ...); 46 | int log_error_cycle(moxi_log *); 47 | 48 | #ifndef MAIN_CHECK 49 | extern moxi_log *ml; 50 | #define moxi_log_write(...) log_error_write (ml, __FILE__, __LINE__, __VA_ARGS__) 51 | #else 52 | #define moxi_log_write(...) fprintf(stderr, __VA_ARGS__) 53 | #endif 54 | 55 | #undef perror 56 | #define perror(str) log_error_write(ml, __FILE__, __LINE__, str, ": %s", strerror(errno)); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /m4/ac_cxx_compile_stdcxx_0x.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://autoconf-archive.cryp.to/ac_cxx_compile_stdcxx_0x.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AC_CXX_COMPILE_STDCXX_0X 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check for baseline language coverage in the compiler for the C++0x 12 | # standard. 13 | # 14 | # LICENSE 15 | # 16 | # Copyright (c) 2008 Benjamin Kosnik 17 | # 18 | # Copying and distribution of this file, with or without modification, are 19 | # permitted in any medium without royalty provided the copyright notice 20 | # and this notice are preserved. 21 | 22 | AC_DEFUN([AC_CXX_COMPILE_STDCXX_0X], [ 23 | AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, 24 | ac_cv_cxx_compile_cxx0x_native, 25 | [AC_LANG_SAVE 26 | AC_LANG_CPLUSPLUS 27 | AC_TRY_COMPILE([ 28 | template 29 | struct check 30 | { 31 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 32 | }; 33 | 34 | typedef check> right_angle_brackets; 35 | 36 | int a; 37 | decltype(a) b; 38 | 39 | typedef check check_type; 40 | check_type c; 41 | check_type&& cr = c;],, 42 | ac_cv_cxx_compile_cxx0x_native=yes, ac_cv_cxx_compile_cxx0x_native=no) 43 | AC_LANG_RESTORE 44 | ]) 45 | 46 | AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, 47 | ac_cv_cxx_compile_cxx0x_cxx, 48 | [AC_LANG_SAVE 49 | AC_LANG_CPLUSPLUS 50 | ac_save_CXXFLAGS="$CXXFLAGS" 51 | CXXFLAGS="$CXXFLAGS -std=c++0x" 52 | AC_TRY_COMPILE([ 53 | template 54 | struct check 55 | { 56 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 57 | }; 58 | 59 | typedef check> right_angle_brackets; 60 | 61 | int a; 62 | decltype(a) b; 63 | 64 | typedef check check_type; 65 | check_type c; 66 | check_type&& cr = c;],, 67 | ac_cv_cxx_compile_cxx0x_cxx=yes, ac_cv_cxx_compile_cxx0x_cxx=no) 68 | CXXFLAGS="$ac_save_CXXFLAGS" 69 | AC_LANG_RESTORE 70 | ]) 71 | 72 | AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, 73 | ac_cv_cxx_compile_cxx0x_gxx, 74 | [AC_LANG_SAVE 75 | AC_LANG_CPLUSPLUS 76 | ac_save_CXXFLAGS="$CXXFLAGS" 77 | CXXFLAGS="$CXXFLAGS -std=gnu++0x" 78 | AC_TRY_COMPILE([ 79 | template 80 | struct check 81 | { 82 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 83 | }; 84 | 85 | typedef check> right_angle_brackets; 86 | 87 | int a; 88 | decltype(a) b; 89 | 90 | typedef check check_type; 91 | check_type c; 92 | check_type&& cr = c;],, 93 | ac_cv_cxx_compile_cxx0x_gxx=yes, ac_cv_cxx_compile_cxx0x_gxx=no) 94 | CXXFLAGS="$ac_save_CXXFLAGS" 95 | AC_LANG_RESTORE 96 | ]) 97 | 98 | if test "$ac_cv_cxx_compile_cxx0x_native" = yes || 99 | test "$ac_cv_cxx_compile_cxx0x_cxx" = yes || 100 | test "$ac_cv_cxx_compile_cxx0x_gxx" = yes; then 101 | AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ]) 102 | fi 103 | ]) 104 | -------------------------------------------------------------------------------- /m4/ac_cxx_header_stdcxx_98.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright © 2008 Benjamin Kosnik 2 | 3 | dnl Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. 4 | 5 | 6 | AC_DEFUN([AC_CXX_HEADER_STDCXX_98], [ 7 | AC_CACHE_CHECK(for ISO C++ 98 include files, 8 | ac_cv_cxx_stdcxx_98, 9 | [AC_LANG_PUSH(C++) 10 | AC_TRY_COMPILE([ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | ],, 61 | ac_cv_cxx_stdcxx_98=yes, ac_cv_cxx_stdcxx_98=no) 62 | AC_LANG_POP() 63 | ]) 64 | if test "$ac_cv_cxx_stdcxx_98" = yes; then 65 | AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ]) 66 | fi 67 | ]) 68 | -------------------------------------------------------------------------------- /m4/pandora_64bit.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl --------------------------------------------------------------------------- 7 | dnl Macro: PANDORA_64BIT 8 | dnl --------------------------------------------------------------------------- 9 | AC_DEFUN([PANDORA_64BIT],[ 10 | AC_BEFORE([$0], [AC_LIB_PREFIX]) 11 | 12 | AC_ARG_ENABLE([64bit], 13 | [AS_HELP_STRING([--disable-64bit], 14 | [Build 64 bit binary @<:@default=on@:>@])], 15 | [ac_enable_64bit="$enableval"], 16 | [ac_enable_64bit="yes"]) 17 | 18 | AC_CHECK_PROGS(ISAINFO, [isainfo], [no]) 19 | AS_IF([test "x$ISAINFO" != "xno"], 20 | [isainfo_b=`${ISAINFO} -b`], 21 | [isainfo_b="x"]) 22 | 23 | AS_IF([test "$isainfo_b" != "x"],[ 24 | 25 | isainfo_k=`${ISAINFO} -k` 26 | DTRACEFLAGS="${DTRACEFLAGS} -${isainfo_b}" 27 | 28 | AS_IF([test "x$ac_enable_64bit" = "xyes"],[ 29 | 30 | AS_IF([test "x${ac_cv_env_LDFLAGS_set}" = "x"],[ 31 | LDFLAGS="-L/usr/local/lib/${isainfo_k} ${LDFLAGS}" 32 | ]) 33 | 34 | AS_IF([test "x$libdir" = "x\${exec_prefix}/lib"],[ 35 | dnl The user hasn't overridden the default libdir, so we'll 36 | dnl the dir suffix to match solaris 32/64-bit policy 37 | libdir="${libdir}/${isainfo_k}" 38 | ]) 39 | 40 | AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],[ 41 | CFLAGS="${CFLAGS} -m64" 42 | ac_cv_env_CFLAGS_set=set 43 | ac_cv_env_CFLAGS_value='-m64' 44 | ]) 45 | AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ 46 | CXXFLAGS="${CXXFLAGS} -m64" 47 | ac_cv_env_CXXFLAGS_set=set 48 | ac_cv_env_CXXFLAGS_value='-m64' 49 | ]) 50 | 51 | AS_IF([test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes"],[ 52 | AM_CFLAGS="-xmemalign=8s ${AM_CFLAGS}" 53 | AM_CXXFLAGS="-xmemalign=8s ${AM_CXXFLAGS}" 54 | ]) 55 | ]) 56 | ]) 57 | ]) 58 | dnl --------------------------------------------------------------------------- 59 | dnl End Macro: PANDORA_64BIT 60 | dnl --------------------------------------------------------------------------- 61 | -------------------------------------------------------------------------------- /m4/pandora_check_compiler_version.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | 7 | AC_DEFUN([PANDORA_CHECK_C_VERSION],[ 8 | 9 | dnl Print version of C compiler 10 | AC_MSG_CHECKING("C Compiler version--$GCC") 11 | AS_IF([test "$GCC" = "yes"],[ 12 | CC_VERSION=`$CC --version | sed 1q` 13 | ],[AS_IF([test "$SUNCC" = "yes"],[ 14 | CC_VERSION=`$CC -V 2>&1 | sed 1q` 15 | ],[ 16 | CC_VERSION="" 17 | ]) 18 | ]) 19 | AC_MSG_RESULT("$CC_VERSION") 20 | AC_SUBST(CC_VERSION) 21 | ]) 22 | 23 | 24 | AC_DEFUN([PANDORA_CHECK_CXX_VERSION], [ 25 | dnl Print version of CXX compiler 26 | AC_MSG_CHECKING("C++ Compiler version") 27 | AS_IF([test "$GCC" = "yes"],[ 28 | CXX_VERSION=`$CXX --version | sed 1q` 29 | ],[AS_IF([test "$SUNCC" = "yes"],[ 30 | CXX_VERSION=`$CXX -V 2>&1 | sed 1q` 31 | ],[ 32 | CXX_VERSION="" 33 | ]) 34 | ]) 35 | AC_MSG_RESULT("$CXX_VERSION") 36 | AC_SUBST(CXX_VERSION) 37 | ]) 38 | -------------------------------------------------------------------------------- /m4/pandora_check_cxx_standard.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_CHECK_CXX_STANDARD],[ 7 | AC_REQUIRE([AC_CXX_COMPILE_STDCXX_0X]) 8 | AS_IF([test "$GCC" = "yes"], 9 | [AS_IF([test "$ac_cv_cxx_compile_cxx0x_native" = "yes"],[], 10 | [AS_IF([test "$ac_cv_cxx_compile_cxx0x_gxx" = "yes"], 11 | [CXXFLAGS="-std=gnu++0x ${CXXFLAGS}"], 12 | [CXXFLAGS="-std=gnu++98"]) 13 | ]) 14 | ]) 15 | AC_CXX_HEADER_STDCXX_98 16 | ]) 17 | -------------------------------------------------------------------------------- /m4/pandora_enable_dtrace.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl --------------------------------------------------------------------------- 7 | dnl Macro: PANDORA_ENABLE_DTRACE 8 | dnl --------------------------------------------------------------------------- 9 | AC_DEFUN([PANDORA_ENABLE_DTRACE],[ 10 | AC_ARG_ENABLE([dtrace], 11 | [AS_HELP_STRING([--enable-dtrace], 12 | [Build with support for the DTRACE. @<:@default=off@:>@])], 13 | [ac_cv_enable_dtrace="yes"], 14 | [ac_cv_enable_dtrace="no"]) 15 | 16 | AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[ 17 | AC_CHECK_PROGS([DTRACE], [dtrace]) 18 | AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[ 19 | AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support]) 20 | AC_MSG_CHECKING([if dtrace should instrument object files]) 21 | dnl DTrace on MacOSX does not use -G option 22 | cat >conftest.d <<_ACEOF 23 | provider Example { 24 | probe increment(int); 25 | }; 26 | _ACEOF 27 | $DTRACE -G -o conftest.d.o -s conftest.d 2>/dev/zero 28 | AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes], 29 | [ac_cv_dtrace_needs_objects=no]) 30 | rm -f conftest.d.o conftest.d 31 | AC_MSG_RESULT($ac_cv_dtrace_needs_objects) 32 | AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX 33 | ac_cv_have_dtrace=yes 34 | ])]) 35 | 36 | AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_have_dtrace" = "xyes"]) 37 | AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS], 38 | [test "x$ac_cv_dtrace_needs_objects" = "xyes"]) 39 | 40 | ]) 41 | dnl --------------------------------------------------------------------------- 42 | dnl End Macro: PANDORA_ENABLE_DTRACE 43 | dnl --------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- /m4/pandora_ensure_gcc_version.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl If the user is on a Mac and didn't ask for a specific compiler 7 | dnl You're gonna get 4.2. 8 | AC_DEFUN([PANDORA_MAC_GCC42], 9 | [AS_IF([test "$GCC" = "yes"],[ 10 | AS_IF([test "$host_vendor" = "apple" -a "x${ac_cv_env_CC_set}" = "x"],[ 11 | host_os_version=`echo ${host_os} | perl -ple 's/^\D+//g;s,\..*,,'` 12 | AS_IF([test "$host_os_version" -lt 10],[ 13 | AS_IF([test -f /usr/bin/gcc-4.2], 14 | [ 15 | CPP="/usr/bin/gcc-4.2 -E" 16 | CC=/usr/bin/gcc-4.2 17 | CXX=/usr/bin/g++-4.2 18 | ]) 19 | ]) 20 | ]) 21 | ]) 22 | ]) 23 | 24 | dnl 25 | AC_DEFUN([PANDORA_ENSURE_GCC_VERSION],[ 26 | AC_REQUIRE([PANDORA_MAC_GCC42]) 27 | AC_CACHE_CHECK([if GCC is recent enough], [ac_cv_gcc_recent], 28 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 29 | #if !defined(__GNUC__) || (__GNUC__ < 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ < 1)) 30 | # error GCC is Too Old! 31 | #endif 32 | ]])], 33 | [ac_cv_gcc_recent=yes], 34 | [ac_cv_gcc_recent=no])]) 35 | AS_IF([test "$ac_cv_gcc_recent" = "no" -a "$host_vendor" = "apple"], 36 | AC_MSG_ERROR([Your version of GCC is too old. At least version 4.2 is required on OSX. You may need to install a version of XCode >= 3.1.2])) 37 | AS_IF([test "$ac_cv_gcc_recent" = "no"], 38 | AC_MSG_ERROR([Your version of GCC is too old. At least version 4.1 is required])) 39 | ]) 40 | -------------------------------------------------------------------------------- /m4/pandora_extensions.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_EXTENSIONS],[ 7 | 8 | m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], 9 | [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], 10 | [AC_REQUIRE([AC_GNU_SOURCE])]) 11 | 12 | ]) 13 | 14 | AC_DEFUN([gl_USE_SYSTEM_EXTENSIONS],[ 15 | AC_REQUIRE([PANDORA_EXTENSIONS]) 16 | ]) 17 | -------------------------------------------------------------------------------- /m4/pandora_have_better_malloc.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_HAVE_BETTER_MALLOC],[ 7 | AC_REQUIRE([AC_FUNC_MALLOC]) 8 | AC_REQUIRE([AC_FUNC_REALLOC]) 9 | AC_REQUIRE([AC_LIB_PREFIX]) 10 | 11 | AC_ARG_ENABLE([umem], 12 | [AS_HELP_STRING([--enable-umem], 13 | [Enable linking with libumem @<:@default=off@:>@])], 14 | [ac_enable_umem="$enableval"],[ 15 | case "$target_os" in 16 | *solaris*) 17 | ac_enable_umem="yes" 18 | ;; 19 | *) 20 | ac_enable_umem="no" 21 | ;; 22 | esac 23 | ]) 24 | 25 | AC_ARG_ENABLE([tcmalloc], 26 | [AS_HELP_STRING([--enable-tcmalloc], 27 | [Enable linking with tcmalloc @<:@default=off@:>@])], 28 | [ac_enable_tcmalloc="$enableval"], 29 | [ac_enable_tcmalloc="no"]) 30 | 31 | AC_ARG_ENABLE([mtmalloc], 32 | [AS_HELP_STRING([--disable-mtmalloc], 33 | [Enable linking with mtmalloc @<:@default=on@:>@])], 34 | [ac_enable_mtmalloc="$enableval"], 35 | [ac_enable_mtmalloc="yes"]) 36 | 37 | save_LIBS="${LIBS}" 38 | LIBS= 39 | AS_IF([test "x$ac_enable_umem" = "xyes"],[ 40 | AC_CHECK_LIB(umem,malloc,[],[]) 41 | ],[ 42 | case "$target_os" in 43 | *linux*) 44 | AS_IF([test "x$ac_enable_tcmalloc" != "xno"],[ 45 | AC_CHECK_LIB(tcmalloc-minimal,malloc,[],[]) 46 | AS_IF([test "x$ac_cv_lib_tcmalloc_minimal_malloc" != "xyes"],[ 47 | AC_CHECK_LIB(tcmalloc,malloc,[],[]) 48 | ]) 49 | ]) 50 | ;; 51 | *solaris*) 52 | AS_IF([test "x$ac_enable_mtmalloc" != "xno"],[ 53 | AC_CHECK_LIB(mtmalloc,malloc,[],[]) 54 | ]) 55 | ;; 56 | esac 57 | ]) 58 | BETTER_MALLOC_LIBS="${LIBS}" 59 | LIBS="${save_LIBS}" 60 | AC_SUBST([BETTER_MALLOC_LIBS]) 61 | 62 | ]) 63 | -------------------------------------------------------------------------------- /m4/pandora_have_innodb.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBINNODB],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libinnodb 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libinnodb], 14 | [AS_HELP_STRING([--disable-libinnodb], 15 | [Build with libinnodb support @<:@default=on@:>@])], 16 | [ac_enable_libinnodb="$enableval"], 17 | [ac_enable_libinnodb="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libinnodb" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(innodb,,[ 21 | #include 22 | ],[ 23 | ib_u64_t 24 | ib_api_version(void); 25 | ]) 26 | ],[ 27 | ac_cv_libinnodb="no" 28 | ]) 29 | 30 | AM_CONDITIONAL(HAVE_LIBINNODB, [test "x${ac_cv_libinnodb}" = "xyes"]) 31 | ]) 32 | 33 | AC_DEFUN([PANDORA_HAVE_LIBINNODB],[ 34 | AC_REQUIRE([_PANDORA_SEARCH_LIBINNODB]) 35 | ]) 36 | 37 | AC_DEFUN([PANDORA_REQUIRE_LIBINNODB],[ 38 | AC_REQUIRE([PANDORA_HAVE_LIBINNODB]) 39 | AS_IF([test "x${ac_cv_libinnodb}" = "xno"], 40 | AC_MSG_ERROR([libinnodb is required for ${PACKAGE}])) 41 | ]) 42 | -------------------------------------------------------------------------------- /m4/pandora_have_libconflate.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2010 NorthScale 2 | dnl This file is free software; NorthScale 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBCONFLATE],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libconflate 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libconflate], 14 | [AS_HELP_STRING([--disable-libconflate], 15 | [Build with libconflate support @<:@default=on@:>@])], 16 | [ac_enable_libconflate="$enableval"], 17 | [ac_enable_libconflate="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libconflate" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(conflate,,[ 21 | #include 22 | ],[ 23 | conflate_config_t config; 24 | ]) 25 | ],[ 26 | ac_cv_libconflate="no" 27 | ]) 28 | 29 | AM_CONDITIONAL(HAVE_LIBCONFLATE, [test "x${ac_cv_libconflate}" = "xyes"]) 30 | ]) 31 | 32 | AC_DEFUN([PANDORA_HAVE_LIBCONFLATE],[ 33 | AC_REQUIRE([_PANDORA_SEARCH_LIBCONFLATE]) 34 | ]) 35 | 36 | AC_DEFUN([PANDORA_REQUIRE_LIBCONFLATE],[ 37 | AC_REQUIRE([PANDORA_HAVE_LIBCONFLATE]) 38 | AS_IF([test x$ac_cv_libconflate = xno], 39 | AC_MSG_ERROR([libconflate is required for ${PACKAGE}])) 40 | ]) 41 | -------------------------------------------------------------------------------- /m4/pandora_have_libdrizzle.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libdrizzle 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libdrizzle], 14 | [AS_HELP_STRING([--disable-libdrizzle], 15 | [Build with libdrizzle support @<:@default=on@:>@])], 16 | [ac_enable_libdrizzle="$enableval"], 17 | [ac_enable_libdrizzle="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(drizzle,,[ 21 | #include 22 | ],[ 23 | drizzle_st drizzle; 24 | drizzle_version(); 25 | ]) 26 | ],[ 27 | ac_cv_libdrizzle="no" 28 | ]) 29 | 30 | AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"]) 31 | ]) 32 | 33 | AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE],[ 34 | AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE]) 35 | ]) 36 | 37 | AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE],[ 38 | AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE]) 39 | AS_IF([test "x${ac_cv_libdrizzle}" = "xno"], 40 | AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}])) 41 | ]) 42 | 43 | AC_DEFUN([PANDORA_LIBDRIZZLE_NOVCOL],[ 44 | AC_CACHE_CHECK([if libdrizzle still has virtual columns], 45 | [pandora_cv_libdrizzle_vcol], 46 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 47 | #include 48 | int foo= DRIZZLE_COLUMN_TYPE_DRIZZLE_VIRTUAL; 49 | ]])], 50 | [pandora_cv_libdrizzle_vcol=yes], 51 | [pandora_cv_libdrizzle_vcol=no])]) 52 | AS_IF([test "$pandora_cv_libdrizzle_vcol" = "yes"],[ 53 | AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.4]) 54 | ]) 55 | ]) 56 | -------------------------------------------------------------------------------- /m4/pandora_have_libevent.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | #-------------------------------------------------------------------- 7 | # Check for libevent 8 | #-------------------------------------------------------------------- 9 | 10 | 11 | AC_DEFUN([_PANDORA_SEARCH_LIBEVENT],[ 12 | AC_REQUIRE([AC_LIB_PREFIX]) 13 | 14 | AC_LIB_HAVE_LINKFLAGS(event,, 15 | [ 16 | #include 17 | #include 18 | #include 19 | #include 20 | ],[ 21 | struct bufferevent bev; 22 | bufferevent_settimeout(&bev, 1, 1); 23 | event_init(); 24 | event_loop(EVLOOP_ONCE); 25 | ]) 26 | 27 | AM_CONDITIONAL(HAVE_LIBEVENT, [test "x${ac_cv_libevent}" = "xyes"]) 28 | 29 | AS_IF([test "x${ac_cv_libevent}" = "xyes"],[ 30 | save_LIBS="${LIBS}" 31 | LIBS="${LIBS} ${LTLIBEVENT}" 32 | AC_CHECK_FUNCS(event_base_new) 33 | AC_CHECK_FUNCS(event_base_free) 34 | AC_CHECK_FUNCS(event_base_get_method) 35 | LIBS="$save_LIBS" 36 | ]) 37 | ]) 38 | 39 | AC_DEFUN([_PANDORA_HAVE_LIBEVENT],[ 40 | 41 | AC_ARG_ENABLE([libevent], 42 | [AS_HELP_STRING([--disable-libevent], 43 | [Build with libevent support @<:@default=on@:>@])], 44 | [ac_enable_libevent="$enableval"], 45 | [ac_enable_libevent="yes"]) 46 | 47 | _PANDORA_SEARCH_LIBEVENT 48 | ]) 49 | 50 | 51 | AC_DEFUN([PANDORA_HAVE_LIBEVENT],[ 52 | AC_REQUIRE([_PANDORA_HAVE_LIBEVENT]) 53 | ]) 54 | 55 | AC_DEFUN([_PANDORA_REQUIRE_LIBEVENT],[ 56 | ac_enable_libevent="yes" 57 | _PANDORA_SEARCH_LIBEVENT 58 | 59 | AS_IF([test x$ac_cv_libevent = xno],[ 60 | AC_MSG_ERROR([libevent is required for ${PACKAGE}. On Debian this can be found in libevent-dev. On RedHat this can be found in libevent-devel.]) 61 | ]) 62 | ]) 63 | 64 | AC_DEFUN([PANDORA_REQUIRE_LIBEVENT],[ 65 | AC_REQUIRE([_PANDORA_REQUIRE_LIBEVENT]) 66 | ]) 67 | -------------------------------------------------------------------------------- /m4/pandora_have_libgearman.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBGEARMAN],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libgearman 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libgearman], 14 | [AS_HELP_STRING([--disable-libgearman], 15 | [Build with libgearman support @<:@default=on@:>@])], 16 | [ac_enable_libgearman="$enableval"], 17 | [ac_enable_libgearman="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libgearman" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(gearman,,[ 21 | #include 22 | ],[ 23 | gearman_client_st gearman_client; 24 | gearman_client_context(&gearman_client); 25 | ]) 26 | ],[ 27 | ac_cv_libgearman="no" 28 | ]) 29 | 30 | AM_CONDITIONAL(HAVE_LIBGEARMAN, [test "x${ac_cv_libgearman}" = "xyes"]) 31 | ]) 32 | 33 | AC_DEFUN([PANDORA_HAVE_LIBGEARMAN],[ 34 | AC_REQUIRE([_PANDORA_SEARCH_LIBGEARMAN]) 35 | ]) 36 | 37 | AC_DEFUN([PANDORA_REQUIRE_LIBGEARMAN],[ 38 | AC_REQUIRE([PANDORA_HAVE_LIBGEARMAN]) 39 | AS_IF([test "x${ac_cv_libgearman}" = "xno"], 40 | AC_MSG_ERROR([At least version 0.10 of libgearman is required for ${PACKAGE}])) 41 | ]) 42 | -------------------------------------------------------------------------------- /m4/pandora_have_libhashkit.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2010 NorthScale 2 | dnl This file is free software; NorthScale 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBHASHKIT],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libhashkit 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libhashkit], 14 | [AS_HELP_STRING([--disable-libhashkit], 15 | [Build with libhashkit support @<:@default=on@:>@])], 16 | [ac_enable_libhashkit="$enableval"], 17 | [ac_enable_libhashkit="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libhashkit" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(hashkit,,[ 21 | #include 22 | ],[ 23 | hashkit_st foo; 24 | hashkit_st *kit = hashkit_create(&foo); 25 | hashkit_free(kit); 26 | ]) 27 | ],[ 28 | ac_cv_libhashkit="no" 29 | ]) 30 | 31 | AM_CONDITIONAL(HAVE_LIBHASHKIT, [test "x${ac_cv_libhashkit}" = "xyes"]) 32 | ]) 33 | 34 | AC_DEFUN([PANDORA_HAVE_LIBHASHKIT],[ 35 | AC_REQUIRE([_PANDORA_SEARCH_LIBHASHKIT]) 36 | ]) 37 | 38 | AC_DEFUN([PANDORA_REQUIRE_LIBHASHKIT],[ 39 | AC_REQUIRE([PANDORA_HAVE_LIBHASHKIT]) 40 | AS_IF([test x$ac_cv_libhashkit = xno], 41 | AC_MSG_ERROR([libhashkit is required for ${PACKAGE}])) 42 | ]) 43 | -------------------------------------------------------------------------------- /m4/pandora_have_libmemcached.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBMEMCACHED],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libmemcached 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libmemcached], 14 | [AS_HELP_STRING([--disable-libmemcached], 15 | [Build with libmemcached support @<:@default=on@:>@])], 16 | [ac_enable_libmemcached="$enableval"], 17 | [ac_enable_libmemcached="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libmemcached" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(memcached,,[ 21 | #include 22 | ],[ 23 | memcached_st memc; 24 | memcached_dump_func *df; 25 | memcached_lib_version(); 26 | ]) 27 | ],[ 28 | ac_cv_libmemcached="no" 29 | ]) 30 | 31 | AM_CONDITIONAL(HAVE_LIBMEMCACHED, [test "x${ac_cv_libmemcached}" = "xyes"]) 32 | 33 | AS_IF([test "x${ac_cv_libmemcached}" = "xyes"], [ PANDORA_WITH_MEMCACHED ]) 34 | ]) 35 | 36 | AC_DEFUN([PANDORA_HAVE_LIBMEMCACHED],[ 37 | AC_REQUIRE([_PANDORA_SEARCH_LIBMEMCACHED]) 38 | ]) 39 | 40 | AC_DEFUN([PANDORA_REQUIRE_LIBMEMCACHED],[ 41 | AC_REQUIRE([PANDORA_HAVE_LIBMEMCACHED]) 42 | AS_IF([test x$ac_cv_libmemcached = xno], 43 | AC_MSG_ERROR([libmemcached is required for ${PACKAGE}])) 44 | ]) 45 | -------------------------------------------------------------------------------- /m4/pandora_have_libpq.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBPQ],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libpq 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libpq], 14 | [AS_HELP_STRING([--disable-libpq], 15 | [Build with libpq support @<:@default=on@:>@])], 16 | [ac_enable_libpq="$enableval"], 17 | [ac_enable_libpq="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libpq" = "xyes"],[ 20 | AC_CHECK_HEADERS([libpq-fe.h]) 21 | AC_LIB_HAVE_LINKFLAGS(pq,,[ 22 | #ifdef HAVE_LIBPQ_FE_H 23 | # include 24 | #else 25 | # include 26 | #endif 27 | ], [ 28 | PGconn *conn; 29 | conn = PQconnectdb(NULL); 30 | ]) 31 | ],[ 32 | ac_cv_libpq="no" 33 | ]) 34 | 35 | AM_CONDITIONAL(HAVE_LIBPQ, [test "x${ac_cv_libpq}" = "xyes"]) 36 | ]) 37 | 38 | AC_DEFUN([PANDORA_HAVE_LIBPQ],[ 39 | AC_REQUIRE([_PANDORA_SEARCH_LIBPQ]) 40 | ]) 41 | 42 | AC_DEFUN([PANDORA_REQUIRE_LIBPQ],[ 43 | AC_REQUIRE([PANDORA_HAVE_LIBPQ]) 44 | AS_IF([test "x${ac_cv_libpq}" = "xno"], 45 | AC_MSG_ERROR([libpq is required for ${PACKAGE}])) 46 | ]) 47 | -------------------------------------------------------------------------------- /m4/pandora_have_libsqlite3.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBSQLITE3],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libsqlite3 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libsqlite3], 14 | [AS_HELP_STRING([--disable-libsqlite3], 15 | [Build with libsqlite3 support @<:@default=on@:>@])], 16 | [ac_enable_libsqlite3="$enableval"], 17 | [ac_enable_libsqlite3="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libsqlite3" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(sqlite3,,[ 21 | #include 22 | #include 23 | ],[ 24 | sqlite3 *db; 25 | sqlite3_open(NULL, &db); 26 | ]) 27 | ],[ 28 | ac_cv_libsqlite3="no" 29 | ]) 30 | 31 | AM_CONDITIONAL(HAVE_LIBSQLITE3, [test "x${ac_cv_libsqlite3}" = "xyes"]) 32 | ]) 33 | 34 | AC_DEFUN([PANDORA_HAVE_LIBSQLITE3],[ 35 | AC_REQUIRE([_PANDORA_SEARCH_LIBSQLITE3]) 36 | ]) 37 | 38 | AC_DEFUN([PANDORA_REQUIRE_LIBSQLITE3],[ 39 | AC_REQUIRE([_PANDORA_SEARCH_LIBSQLITE3]) 40 | AS_IF([test "x${ac_cv_libsqlite3}" = "xno"], 41 | AC_MSG_ERROR([libsqlite3 is required for ${PACKAGE}])) 42 | ]) 43 | -------------------------------------------------------------------------------- /m4/pandora_have_libvbucket.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2010 NorthScale 2 | dnl This file is free software; NorthScale 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([_PANDORA_SEARCH_LIBVBUCKET],[ 7 | AC_REQUIRE([AC_LIB_PREFIX]) 8 | 9 | dnl -------------------------------------------------------------------- 10 | dnl Check for libvbucket 11 | dnl -------------------------------------------------------------------- 12 | 13 | AC_ARG_ENABLE([libvbucket], 14 | [AS_HELP_STRING([--disable-libvbucket], 15 | [Build with libvbucket support @<:@default=on@:>@])], 16 | [ac_enable_libvbucket="$enableval"], 17 | [ac_enable_libvbucket="yes"]) 18 | 19 | AS_IF([test "x$ac_enable_libvbucket" = "xyes"],[ 20 | AC_LIB_HAVE_LINKFLAGS(vbucket,,[ 21 | #include 22 | ],[ 23 | VBUCKET_CONFIG_HANDLE config = vbucket_config_parse_file(NULL); 24 | ]) 25 | ],[ 26 | ac_cv_libvbucket="no" 27 | ]) 28 | 29 | AM_CONDITIONAL(HAVE_LIBVBUCKET, [test "x${ac_cv_libvbucket}" = "xyes"]) 30 | ]) 31 | 32 | AC_DEFUN([PANDORA_HAVE_LIBVBUCKET],[ 33 | AC_REQUIRE([_PANDORA_SEARCH_LIBVBUCKET]) 34 | ]) 35 | 36 | AC_DEFUN([PANDORA_REQUIRE_LIBVBUCKET],[ 37 | AC_REQUIRE([PANDORA_HAVE_LIBVBUCKET]) 38 | AS_IF([test x$ac_cv_libvbucket = xno], 39 | AC_MSG_ERROR([libvbucket is required for ${PACKAGE}])) 40 | ]) 41 | -------------------------------------------------------------------------------- /m4/pandora_have_protobuf.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | dnl -------------------------------------------------------------------- 13 | dnl Check for Google Proto Buffers 14 | dnl -------------------------------------------------------------------- 15 | 16 | AC_DEFUN([_PANDORA_SEARCH_LIBPROTOBUF],[ 17 | AC_REQUIRE([PANDORA_HAVE_PTHREAD]) 18 | 19 | AC_LANG_PUSH([C++]) 20 | save_CXXFLAGS="${CXXFLAGS}" 21 | CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}" 22 | AC_LIB_HAVE_LINKFLAGS(protobuf,, 23 | [#include ], 24 | [google::protobuf::FileDescriptor* file;], 25 | [system]) 26 | CXXFLAGS="${save_CXXFLAGS}" 27 | AC_LANG_POP() 28 | ]) 29 | 30 | AC_DEFUN([PANDORA_HAVE_LIBPROTOBUF],[ 31 | AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF]) 32 | ]) 33 | 34 | AC_DEFUN([PANDORA_REQUIRE_LIBPROTOBUF],[ 35 | AC_REQUIRE([PANDORA_HAVE_LIBPROTOBUF]) 36 | AS_IF([test x$ac_cv_libprotobuf = xno], 37 | AC_MSG_ERROR([libprotobuf is required for ${PACKAGE}. On Debian this can be found in libprotobuf-dev. On RedHat this can be found in protobuf-devel.])) 38 | ]) 39 | 40 | AC_DEFUN([PANDORA_PROTOBUF_REQUIRE_VERSION],[ 41 | AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF]) 42 | p_recent_ver=$1 43 | p_recent_ver_major=`echo $p_recent_ver | cut -f1 -d.` 44 | p_recent_ver_minor=`echo $p_recent_ver | cut -f2 -d.` 45 | p_recent_ver_patch=`echo $p_recent_ver | cut -f3 -d.` 46 | p_recent_ver_hex=`printf "%d%03d%03d" $p_recent_ver_major $p_recent_ver_minor $p_recent_ver_patch` 47 | AC_LANG_PUSH([C++]) 48 | AC_CACHE_CHECK([for protobuf >= $p_recent_ver], 49 | [drizzle_cv_protobuf_recent], 50 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 51 | #include 52 | #if GOOGLE_PROTOBUF_VERSION < $p_recent_ver_hex 53 | # error Your version of Protobuf is too old 54 | #endif 55 | ]])], 56 | [drizzle_cv_protobuf_recent=yes], 57 | [drizzle_cv_protobuf_recent=no])]) 58 | AS_IF([test "$drizzle_cv_protobuf_recent" = "no"],[ 59 | AC_MSG_ERROR([Your version of Google Protocol Buffers is too old. ${PACKAGE} requires at least version $p_recent_ver]) 60 | ]) 61 | AC_LANG_POP() 62 | ]) 63 | 64 | AC_DEFUN([_PANDORA_SEARCH_PROTOC],[ 65 | AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF]) 66 | AC_PATH_PROG([PROTOC],[protoc],[no],[$LIBPROTOBUF_PREFIX/bin:$PATH]) 67 | ]) 68 | 69 | AC_DEFUN([PANDORA_HAVE_PROTOC],[ 70 | AC_REQUIRE([_PANDORA_SEARCH_PROTOC]) 71 | ]) 72 | 73 | AC_DEFUN([PANDORA_REQUIRE_PROTOC],[ 74 | AC_REQUIRE([PANDORA_HAVE_PROTOC]) 75 | AS_IF([test "x$PROTOC" = "xno"],[ 76 | AC_MSG_ERROR([Couldn't find the protoc compiler. On Debian this can be found in protobuf-compiler. On RedHat this can be found in protobuf-compiler.]) 77 | ]) 78 | ]) 79 | 80 | 81 | -------------------------------------------------------------------------------- /m4/pandora_header_assert.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl PANDORA_HEADER_ASSERT 7 | dnl ---------------- 8 | dnl Check whether to enable assertions. 9 | AC_DEFUN([PANDORA_HEADER_ASSERT], 10 | [ 11 | AC_MSG_CHECKING([whether to enable assertions]) 12 | AC_ARG_ENABLE([assert], 13 | [AS_HELP_STRING([--disable-assert], 14 | [Turn off assertions])], 15 | [ac_cv_assert="no"], 16 | [ac_cv_assert="yes"]) 17 | AC_MSG_RESULT([$ac_cv_assert]) 18 | 19 | AS_IF([test "$ac_cv_assert" = "yes"], 20 | [AC_CHECK_HEADERS(assert.h)], 21 | [AC_DEFINE(NDEBUG, 1, [Define to 1 if assertions should be disabled.])]) 22 | ]) 23 | 24 | -------------------------------------------------------------------------------- /m4/pandora_libtool.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_LIBTOOL],[ 7 | AC_REQUIRE([AC_PROG_LIBTOOL]) 8 | dnl By requiring AC_PROG_LIBTOOL, we should force the macro system to read 9 | dnl libtool.m4, where in 2.2 AC_PROG_LIBTOOL is an alias for LT_INIT 10 | dnl Then, if we're on 2.2, we should have LT_LANG, so we'll call it. 11 | m4_ifdef([LT_LANG],[ 12 | LT_LANG(C) 13 | LT_LANG(C++) 14 | ]) 15 | ]) 16 | -------------------------------------------------------------------------------- /m4/pandora_optimize.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_OPTIMIZE],[ 7 | dnl Build optimized or debug version ? 8 | dnl First check for gcc and g++ 9 | AS_IF([test "$GCC" = "yes" -a "$INTELCC" = "no"],[ 10 | 11 | dnl The following is required for portable results of floating point 12 | dnl calculations on PowerPC. The same must also be done for IA-64, but 13 | dnl this options is missing in the IA-64 gcc backend. 14 | case "$target_cpu" in 15 | *ppc* | *powerpc*) 16 | AM_CFLAGS="-mno-fused-madd ${AM_CFLAGS}" 17 | AM_CXXFLAGS="-mno-fused-madd ${AM_CXXFLAGS}" 18 | ;; 19 | esac 20 | 21 | dnl Once we can use a modern autoconf, we can replace the std=gnu99 here 22 | dnl with using AC_CC_STD_C99 above 23 | CC="${CC} -std=gnu99" 24 | 25 | AM_CPPFLAGS="-ggdb3 ${AM_CPPFLAGS}" 26 | 27 | DEBUG_CFLAGS="-O0" 28 | DEBUG_CXXFLAGS="-O0" 29 | 30 | OPTIMIZE_CFLAGS="-O3" 31 | OPTIMIZE_CXXFLAGS="-O3" 32 | ]) 33 | AS_IF([test "$INTELCC" = "yes"],[ 34 | dnl Once we can use a modern autoconf, we can replace the std=gnu99 here 35 | dnl with using AC_CC_STD_C99 above 36 | CC="${CC} -std=c99" 37 | 38 | AM_CPPFLAGS="-g ${AM_CPPFLAGS}" 39 | 40 | DEBUG_CFLAGS="-O0" 41 | DEBUG_CXXFLAGS="-O0" 42 | 43 | OPTIMIZE_CFLAGS="-xHOST -O3 -no-prec-div -static" 44 | OPTIMIZE_CXXFLAGS="${OPTIMIZE_CFLAGS}" 45 | 46 | ]) 47 | AS_IF([test "$SUNCC" = "yes"],[ 48 | dnl Once we can use a modern autoconf, we can replace the -xc99=all here 49 | dnl with using AC_CC_STD_C99 above 50 | CC="${CC} -xc99=all" 51 | CXX="${CXX} -xlang=c99" 52 | 53 | AM_CFLAGS="-g -mt -xstrconst -Xa ${AM_CFLAGS}" 54 | AM_CXXFLAGS="-mt -compat=5 -library=stlport4 -template=no%extdef ${AM_CXXFLAGS}" 55 | 56 | DEBUG_CXXFLAGS="-g" 57 | 58 | dnl TODO: Make a test for -xO4 usability here 59 | OPTIMIZE_FLAGS="-xO3 -xlibmil -xdepend -xbuiltin" 60 | OPTIMIZE_CFLAGS="${OPTIMIZE_FLAGS}" 61 | OPTIMIZE_CXXFLAGS="-g0 ${OPTIMIZE_FLAGS}" 62 | 63 | ]) 64 | 65 | AC_ARG_WITH([debug], 66 | [AS_HELP_STRING([--with-debug], 67 | [Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])], 68 | [with_debug=$withval], 69 | [with_debug=no]) 70 | AS_IF([test "$with_debug" = "yes"],[ 71 | # Debugging. No optimization. 72 | AM_CFLAGS="${AM_CFLAGS} ${DEBUG_CFLAGS} -DDEBUG" 73 | AM_CXXFLAGS="${AM_CXXFLAGS} ${DEBUG_CXXFLAGS} -DDEBUG" 74 | ],[ 75 | # Optimized version. No debug 76 | AM_CFLAGS="${AM_CFLAGS} ${OPTIMIZE_CFLAGS}" 77 | AM_CXXFLAGS="${AM_CXXFLAGS} ${OPTIMIZE_CXXFLAGS}" 78 | ]) 79 | ]) 80 | -------------------------------------------------------------------------------- /m4/pandora_platform.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | AC_DEFUN([PANDORA_PLATFORM],[ 13 | 14 | dnl Canonicalize the configuration name. 15 | 16 | AC_DEFINE_UNQUOTED([HOST_VENDOR], ["$host_vendor"],[Vendor of Build System]) 17 | AC_DEFINE_UNQUOTED([HOST_OS], ["$host_os"], [OS of Build System]) 18 | AC_DEFINE_UNQUOTED([HOST_CPU], ["$host_cpu"], [CPU of Build System]) 19 | 20 | AC_DEFINE_UNQUOTED([TARGET_VENDOR], ["$target_vendor"],[Vendor of Target System]) 21 | AC_DEFINE_UNQUOTED([TARGET_OS], ["$target_os"], [OS of Target System]) 22 | AC_DEFINE_UNQUOTED([TARGET_CPU], ["$target_cpu"], [CPU of Target System]) 23 | 24 | 25 | case "$host_os" in 26 | *solaris*|*freebsd*) 27 | AS_IF([test "x${ac_cv_env_CPPFLAGS_set}" = "x"],[ 28 | CPPFLAGS="${CPPFLAGS} -I/usr/local/include" 29 | ]) 30 | 31 | AS_IF([test "x${ac_cv_env_LDFLAGS_set}" = "x"],[ 32 | LDFLAGS="${LDFLAGS} -L/usr/local/lib" 33 | ]) 34 | ;; 35 | esac 36 | 37 | case "$target_os" in 38 | *linux*) 39 | TARGET_LINUX="true" 40 | AC_SUBST(TARGET_LINUX) 41 | AC_DEFINE([TARGET_OS_LINUX], [1], [Whether we build for Linux]) 42 | ;; 43 | *darwin*) 44 | TARGET_OSX="true" 45 | AC_SUBST(TARGET_OSX) 46 | AC_DEFINE([TARGET_OS_OSX], [1], [Whether we build for OSX]) 47 | ;; 48 | *solaris*) 49 | TARGET_SOLARIS="true" 50 | AC_SUBST(TARGET_SOLARIS) 51 | AC_DEFINE([TARGET_OS_SOLARIS], [1], [Whether we are building for Solaris]) 52 | ;; 53 | *freebsd*) 54 | TARGET_FREEBSD="true" 55 | AC_SUBST(TARGET_FREEBSD) 56 | AC_DEFINE([TARGET_OS_FREEBSD], [1], [Whether we are building for FreeBSD]) 57 | AC_DEFINE([__APPLE_CC__],[1],[Workaround for bug in FreeBSD headers]) 58 | ;; 59 | *) 60 | ;; 61 | esac 62 | 63 | AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) 64 | AC_CHECK_DECL([__ICC], [INTELCC="yes"], [INTELCC="no"]) 65 | 66 | AS_IF([test "$INTELCC" = "yes"], [enable_rpath=no]) 67 | 68 | dnl By default, Sun Studio grabs special versions of limits.h and string.h 69 | dnl when you use and . By setting this define, we can 70 | dnl disable that and cause those to wrap the standard headers instead. 71 | dnl http://www.stlport.com/doc/configure.html 72 | AS_IF([test "$SUNCC" = "yes"],[ 73 | AC_DEFINE([_STLP_NO_NEW_C_HEADERS],[1], 74 | [Cause Sun Studio to not be quite so strict with standards conflicts]) 75 | ]) 76 | 77 | ]) 78 | -------------------------------------------------------------------------------- /m4/pandora_plugins.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | dnl-------------------------------------------------------------------- 6 | dnl PANDORA_PLUGINS 7 | dnl Declare our plugin modules 8 | dnl-------------------------------------------------------------------- 9 | 10 | AC_DEFUN([PANDORA_PLUGINS],[ 11 | 12 | m4_sinclude(config/plugin.ac) 13 | dnl Add code here to read set plugin lists and set drizzled_default_plugin_list 14 | AC_DEFINE_UNQUOTED([PANDORA_PLUGIN_LIST],[$pandora_default_plugin_list], 15 | [List of plugins that should be loaded on startup if no 16 | value is given for --plugin-load]) 17 | 18 | pandora_builtin_list=`echo $pandora_builtin_list | sed 's/, *$//'` 19 | AS_IF([test "x$pandora_builtin_list" = "x"], pandora_builtin_list="NULL") 20 | AC_SUBST([PANDORA_BUILTIN_LIST],[$pandora_builtin_list]) 21 | m4_ifval(m4_normalize([$1]),[ 22 | AC_CONFIG_FILES($*) 23 | ],[ 24 | AC_DEFINE_UNQUOTED([PANDORA_BUILTIN_LIST],[$pandora_builtin_list], 25 | [List of plugins to be built in]) 26 | ]) 27 | 28 | 29 | AC_SUBST(pandora_plugin_test_list) 30 | AC_SUBST(pandora_plugin_libs) 31 | 32 | pandora_plugin_defs=`echo $pandora_plugin_defs | sed 's/, *$//'` 33 | AC_SUBST(pandora_plugin_defs) 34 | 35 | AC_SUBST(PANDORA_PLUGIN_DEP_LIBS) 36 | AC_SUBST(pkgplugindir,"\$(pkglibdir)/plugin") 37 | ]) 38 | 39 | AC_DEFUN([PANDORA_ADD_PLUGIN_DEP_LIB],[ 40 | PANDORA_PLUGIN_DEP_LIBS="${PANDORA_PLUGIN_DEP_LIBS} $*" 41 | ]) 42 | -------------------------------------------------------------------------------- /m4/pandora_print_callstack.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl Try to define a macro to dump the current callstack. 7 | AC_DEFUN([PANDORA_PRINT_CALLSTACK],[ 8 | AC_CHECK_HEADERS([ucontext.h]) 9 | AS_IF([test "x$ac_cv_header_ucontext_h" = "xyes"], 10 | [ AC_CHECK_FUNCS([printstack]) ]) 11 | 12 | AS_IF([ test "x$ac_cv_func_printstack" != "xyes"], 13 | [ AC_CHECK_HEADERS([dlfcn.h]) 14 | AC_CHECK_HEADERS([execinfo.h]) 15 | AC_CHECK_FUNCS([backtrace]) 16 | AC_CHECK_FUNCS([backtrace_symbols_fd]) ]) 17 | 18 | AH_BOTTOM([ 19 | #ifdef __cplusplus 20 | #include 21 | #define PANDORA_PRINTSTACK_STD_PREFIX std:: 22 | #else 23 | #include 24 | #define PANDORA_PRINTSTACK_STD_PREFIX 25 | #endif 26 | 27 | #if defined(HAVE_UCONTEXT_H) && defined(HAVE_PRINTSTACK) 28 | #include 29 | #define pandora_print_callstack(a) \ 30 | printstack(PANDORA_PRINTSTACK_STD_PREFIX fileno(a)) 31 | #elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD) 32 | 33 | #include 34 | 35 | #define pandora_print_callstack(a) \ 36 | { \ 37 | void *stack[100]; \ 38 | int depth = backtrace(stack, 100); \ 39 | backtrace_symbols_fd(stack, depth, PANDORA_PRINTSTACK_STD_PREFIX fileno(a)); \ 40 | } 41 | #elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) && !defined(HAVE_BACKTRACE_SYMBOLS_FD) 42 | 43 | #include 44 | 45 | #define pandora_print_callstack(a) \ 46 | { \ 47 | void *stack[100]; \ 48 | int depth= backtrace(stack, 100); \ 49 | char **symbol= backtrace_symbols(stack, depth); \ 50 | for (int x= 0; x < size; ++x) \ 51 | PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, "%s\n", symbol[x]); \ 52 | } 53 | #else 54 | #define pandora_print_callstack(a) \ 55 | PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, \ 56 | "Stackdump not supported for this platform\n"); 57 | #endif 58 | ]) 59 | ]) 60 | -------------------------------------------------------------------------------- /m4/pandora_pthread.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | 13 | dnl -------------------------------------------------------------------- 14 | dnl Check for libpthread 15 | dnl -------------------------------------------------------------------- 16 | 17 | AC_DEFUN([PANDORA_PTHREAD_YIELD],[ 18 | AC_REQUIRE([ACX_PTHREAD]) 19 | 20 | save_CFLAGS="${CFLAGS}" 21 | save_CXXFLAGS="${CXXFLAGS}" 22 | CFLAGS="${PTHREAD_CFLAGS} ${CFLAGS}" 23 | CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}" 24 | dnl Some OSes like Mac OS X have that as a replacement for pthread_yield() 25 | AC_CHECK_FUNCS(pthread_yield_np) 26 | AC_CACHE_CHECK([if pthread_yield takes zero arguments], 27 | [pandora_cv_pthread_yield_zero_arg], 28 | [AC_LINK_IFELSE([ 29 | AC_LANG_PROGRAM([[ 30 | #include 31 | ]],[[ 32 | pthread_yield(); 33 | ]])], 34 | [pandora_cv_pthread_yield_zero_arg=yes], 35 | [pandora_cv_pthread_yield_zero_arg=no])]) 36 | AS_IF([test "$pandora_cv_pthread_yield_zero_arg" = "yes"],[ 37 | AC_DEFINE([HAVE_PTHREAD_YIELD_ZERO_ARG], [1], 38 | [pthread_yield that doesn't take any arguments]) 39 | ]) 40 | 41 | AC_CACHE_CHECK([if pthread_yield takes one argument], 42 | [pandora_cv_pthread_yield_one_arg], 43 | [AC_LINK_IFELSE([ 44 | AC_LANG_PROGRAM([[ 45 | #include 46 | ]],[[ 47 | pthread_yield(0); 48 | ]])], 49 | [pandora_cv_pthread_yield_one_arg=yes], 50 | [pandora_cv_pthread_yield_one_arg=no])]) 51 | AS_IF([test "$pandora_cv_pthread_yield_one_arg" = "yes"],[ 52 | AC_DEFINE([HAVE_PTHREAD_YIELD_ONE_ARG], [1], 53 | [pthread_yield function with one argument]) 54 | ]) 55 | 56 | CFLAGS="${save_CFLAGS}" 57 | CXXFLAGS="${save_CXXFLAGS}" 58 | ]) 59 | 60 | 61 | AC_DEFUN([_PANDORA_SEARCH_PTHREAD],[ 62 | AC_REQUIRE([ACX_PTHREAD]) 63 | LIBS="${PTHREAD_LIBS} ${LIBS}" 64 | AM_CFLAGS="${PTHREAD_CFLAGS} ${AM_CFLAGS}" 65 | AM_CXXFLAGS="${PTHREAD_CFLAGS} ${AM_CXXFLAGS}" 66 | PANDORA_PTHREAD_YIELD 67 | ]) 68 | 69 | 70 | AC_DEFUN([PANDORA_HAVE_PTHREAD],[ 71 | AC_REQUIRE([_PANDORA_SEARCH_PTHREAD]) 72 | ]) 73 | 74 | AC_DEFUN([PANDORA_REQUIRE_PTHREAD],[ 75 | AC_REQUIRE([PANDORA_HAVE_PTHREAD]) 76 | AS_IF([test "x$acx_pthread_ok" != "xyes"],[ 77 | AC_MSG_ERROR(could not find libpthread)]) 78 | ]) 79 | -------------------------------------------------------------------------------- /m4/pandora_shared_ptr.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | dnl We check two things: where is the memory include file, and in what 7 | dnl namespace does shared_ptr reside. 8 | dnl We include AC_COMPILE_IFELSE for all the combinations we've seen in the 9 | dnl wild: 10 | dnl 11 | dnl GCC 4.3: namespace: std:: #include 12 | dnl GCC 4.2: namespace: tr1:: #include 13 | dnl GCC 4.2: namespace: boost:: #include 14 | dnl 15 | dnl We define one of HAVE_HAVE_TR1_SHARED_PTR or HAVE_BOOST_SHARED_PTR 16 | dnl depending on location, and SHARED_PTR_NAMESPACE to be the namespace in 17 | dnl which shared_ptr is defined. 18 | dnl 19 | 20 | AC_DEFUN([PANDORA_SHARED_PTR],[ 21 | AC_REQUIRE([PANDORA_CHECK_CXX_STANDARD]) 22 | AC_LANG_PUSH(C++) 23 | AC_CHECK_HEADERS(memory tr1/memory boost/shared_ptr.hpp) 24 | AC_CACHE_CHECK([the location of shared_ptr header file], 25 | [ac_cv_shared_ptr_h],[ 26 | for namespace in std tr1 std::tr1 boost 27 | do 28 | AC_COMPILE_IFELSE( 29 | [AC_LANG_PROGRAM([[ 30 | #if defined(HAVE_MEMORY) 31 | # include 32 | #endif 33 | #if defined(HAVE_TR1_MEMORY) 34 | # include 35 | #endif 36 | #if defined(HAVE_BOOST_SHARED_PTR_HPP) 37 | # include 38 | #endif 39 | #include 40 | 41 | using $namespace::shared_ptr; 42 | using namespace std; 43 | ]],[[ 44 | shared_ptr test_ptr(new string("test string")); 45 | ]])], 46 | [ 47 | ac_cv_shared_ptr_namespace="${namespace}" 48 | break 49 | ],[ac_cv_shared_ptr_namespace=missing]) 50 | done 51 | ]) 52 | AC_DEFINE_UNQUOTED([SHARED_PTR_NAMESPACE], 53 | ${ac_cv_shared_ptr_namespace}, 54 | [The namespace in which SHARED_PTR can be found]) 55 | AC_LANG_POP() 56 | ]) 57 | -------------------------------------------------------------------------------- /m4/pandora_swig.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystem 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | AC_DEFUN([PANDORA_SWIG],[ 13 | 14 | AC_PROG_SWIG(1.3.31) 15 | 16 | AC_DEFINE_UNQUOTED([SWIG_TYPE_TABLE], 17 | [$PACKAGE], 18 | [Type Table name for SWIG symbol table]) 19 | 20 | dnl Have to hard-code /usr/local/include and /usr/include into the path. 21 | dnl I hate this. Why is swig sucking me 22 | SWIG="$SWIG \${DEFS} -I\${top_srcdir} -I\${top_builddir} -I/usr/local/include -I/usr/include" 23 | AC_SUBST([SWIG]) 24 | 25 | 26 | ]) 27 | 28 | AC_DEFUN([PANDORA_SWIG_PYTHON3],[ 29 | AC_REQUIRE([PANDORA_SWIG]) 30 | AS_IF([test "x$SWIG" != "x"],[ 31 | AC_CACHE_CHECK([if swig supports Python3], 32 | [ac_cv_swig_has_python3_], 33 | [ 34 | AS_IF([$SWIG -python -help 2>&1 | grep py3 > /dev/null], 35 | [ac_cv_swig_has_python3_=yes], 36 | [ac_cv_swig_has_python3_=no]) 37 | ]) 38 | ]) 39 | ]) 40 | -------------------------------------------------------------------------------- /m4/pandora_use_pipe.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystem 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | dnl 12 | dnl Test if we can Use -pipe to avoid making temp files during the compile. 13 | dnl Should speed up compile on slower disks 14 | 15 | AC_DEFUN([PANDORA_USE_PIPE],[ 16 | 17 | AS_IF([test "$GCC" = "yes"],[ 18 | AC_CACHE_CHECK([for working -pipe], [pandora_cv_use_pipe], [ 19 | AC_LINK_IFELSE([AC_LANG_SOURCE([[ 20 | #include 21 | 22 | int main(int argc, char** argv) 23 | { 24 | (void) argc; (void) argv; 25 | return 0; 26 | } 27 | ]])], 28 | [pandora_cv_use_pipe=yes], 29 | [pandora_cv_use_pipe=no]) 30 | ]) 31 | AS_IF([test "$pandora_cv_use_pipe" = "yes"],[ 32 | AM_CFLAGS="-pipe ${AM_CFLAGS}" 33 | AM_CXXFLAGS="-pipe ${AM_CXXFLAGS}" 34 | ]) 35 | ]) 36 | ]) 37 | -------------------------------------------------------------------------------- /m4/pandora_vc_build.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_BUILDING_FROM_VC],[ 7 | 8 | ac_cv_building_from_vc=no 9 | 10 | AS_IF([test -d "${srcdir}/.bzr"],[ 11 | ac_cv_building_from_bzr=yes 12 | ac_cv_building_from_vc=yes 13 | ],[ 14 | ac_cv_building_from_bzr=no 15 | ]) 16 | 17 | AS_IF([test -d "${srcdir}/.svn"],[ 18 | ac_cv_building_from_svn=yes 19 | ac_cv_building_from_vc=yes 20 | ],[ 21 | ac_cv_building_from_svn=no 22 | ]) 23 | 24 | AS_IF([test -d "${srcdir}/.hg"],[ 25 | ac_cv_building_from_hg=yes 26 | ac_cv_building_from_vc=yes 27 | ],[ 28 | ac_cv_building_from_hg=no 29 | ]) 30 | 31 | AS_IF([test -d "${srcdir}/.git"],[ 32 | ac_cv_building_from_git=yes 33 | ac_cv_building_from_vc=yes 34 | ],[ 35 | ac_cv_building_from_git=no 36 | ]) 37 | 38 | 39 | ]) 40 | 41 | dnl Takes one argument which is the prefix to append 42 | AC_DEFUN([PANDORA_EXPORT_BZR_INFO],[ 43 | m4_ifval(m4_normalize([$1]),[ 44 | m4_define([PEBI_PREFIX],[]) 45 | ],[ 46 | m4_define([PEBI_PREFIX],m4_toupper(m4_normalize($1))[_]) 47 | ]) 48 | 49 | AC_DEFINE(PEBI_PREFIX[BZR_REVID], ["BZR_REVID"], [bzr revision ID]) 50 | AC_DEFINE(PEBI_PREFIX[BZR_BRANCH], ["BZR_BRANCH"], [bzr branch name]) 51 | AC_DEFINE(PEBI_PREFIX[RELEASE_DATE], ["RELEASE_DATE"], [Release date based on the date of the repo checkout]) 52 | AC_DEFINE(PEBI_PREFIX[RELEASE_VERSION], ["RELEASE_VERSION"], [$1 version number formatted for display]) 53 | AC_DEFINE(PEBI_PREFIX[RELEASE_COMMENT], ["RELEASE_COMMENT"], [Set to trunk if the branch is the main $1 branch]) 54 | AC_DEFINE(PEBI_PREFIX[RELEASE_ID], [RELEASE_ID], [$1 version number formatted for numerical comparison]) 55 | 56 | ]) 57 | 58 | -------------------------------------------------------------------------------- /m4/pandora_with_lua.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | AC_DEFUN([PANDORA_WITH_LUA],[ 13 | dnl Check for lua 14 | AC_ARG_WITH([lua], 15 | [AS_HELP_STRING([--with-lua], 16 | [Build Lua Bindings @<:@default=yes@:>@])], 17 | [with_lua=$withval], 18 | [with_lua=yes]) 19 | 20 | AS_IF([test "x$with_lua" != "xno"],[ 21 | AS_IF([test "x$with_lua" = "xyes"], 22 | [LUAPC=lua], 23 | [LUAPC=$with_lua]) 24 | 25 | PKG_CHECK_MODULES([LUA], $LUAPC >= 5.1, [ 26 | AC_DEFINE([HAVE_LUA], [1], [liblua]) 27 | AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) 28 | with_lua=yes 29 | ],[ 30 | LUAPC=lua5.1 31 | PKG_CHECK_MODULES([LUA], $LUAPC >= 5.1, [ 32 | AC_DEFINE([HAVE_LUA], [1], [liblua]) 33 | AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) 34 | with_lua=yes 35 | ],[ 36 | AC_DEFINE([HAVE_LUA],["x"],["x"]) 37 | with_lua=no 38 | ]) 39 | ]) 40 | 41 | AC_CACHE_CHECK([for LUA installation location],[pandora_cv_lua_archdir],[ 42 | AS_IF([test "$prefix" = "NONE"],[ 43 | pandora_cv_lua_archdir=`${PKG_CONFIG} --define-variable=prefix=${ac_default_prefix} --variable=INSTALL_CMOD ${LUAPC}` 44 | ],[ 45 | pandora_cv_lua_archdir=`${PKG_CONFIG} --define-variable=prefix=${prefix} --variable=INSTALL_CMOD ${LUAPC}` 46 | ]) 47 | ]) 48 | LUA_ARCHDIR="${pandora_cv_lua_archdir}" 49 | AC_SUBST(LUA_ARCHDIR) 50 | AC_SUBST(LUA_CFLAGS) 51 | AC_SUBST(LUA_LIBS) 52 | ]) 53 | AM_CONDITIONAL(BUILD_LUA, test "$with_lua" = "yes") 54 | 55 | ]) 56 | -------------------------------------------------------------------------------- /m4/pandora_with_memcached.m4: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2009 Sun Microsystems 2 | dnl This file is free software; Sun Microsystems 3 | dnl gives unlimited permission to copy and/or distribute it, 4 | dnl with or without modifications, as long as this notice is preserved. 5 | 6 | AC_DEFUN([PANDORA_WITH_MEMCACHED],[ 7 | 8 | AC_ARG_WITH([memcached], 9 | [AS_HELP_STRING([--with-memcached], 10 | [Memcached binary to use for make test])], 11 | [ac_cv_with_memcached="$withval"], 12 | [ac_cv_with_memcached=memcached]) 13 | 14 | # just ignore the user if --without-memcached is passed.. it is 15 | # only used by make test 16 | AS_IF([test "x$withval" = "xno"],[ 17 | ac_cv_with_memcached=memcached 18 | MEMCACHED_BINARY=memcached 19 | ],[ 20 | AS_IF([test -f "$withval"],[ 21 | ac_cv_with_memcached=$withval 22 | MEMCACHED_BINARY=$withval 23 | ],[ 24 | AC_PATH_PROG([MEMCACHED_BINARY], [$ac_cv_with_memcached], "no") 25 | AS_IF([test "x$MEMCACHED_BINARY" = "xno"],[ 26 | AC_MSG_ERROR(["could not find memcached binary"]) 27 | ]) 28 | ]) 29 | ]) 30 | AC_DEFINE_UNQUOTED([MEMCACHED_BINARY], "$MEMCACHED_BINARY", 31 | [Name of the memcached binary used in make test]) 32 | 33 | ]) 34 | -------------------------------------------------------------------------------- /m4/pandora_with_perl.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | 13 | AC_DEFUN([PANDORA_WITH_PERL], [ 14 | 15 | AC_ARG_WITH([perl], 16 | [AS_HELP_STRING([--with-perl], 17 | [Build Perl Bindings @<:@default=yes@:>@])], 18 | [with_perl=$withval], 19 | [with_perl=yes]) 20 | 21 | AC_ARG_WITH([perl-arch], 22 | [AS_HELP_STRING([--with-perl-arch], 23 | [Install Perl bindings into system location @<:@default=no@:>@])], 24 | [with_perl_arch=$withval], 25 | [with_perl_arch=no]) 26 | 27 | AS_IF([test "x$with_perl" != "xno"],[ 28 | AS_IF([test "x$with_perl" != "xyes"], 29 | [ac_chk_perl=$with_perl], 30 | [ac_chk_perl=perl]) 31 | AC_CHECK_PROGS(PERL,$ac_chk_perl) 32 | ]) 33 | AS_IF([test "x$PERL" != "x"],[ 34 | AC_CACHE_CHECK([for Perl include path],[pandora_cv_perl_include],[ 35 | pandora_cv_perl_include=`$PERL -MConfig -e 'print $Config{archlib};'` 36 | pandora_cv_perl_include="${pandora_cv_perl_include}/CORE" 37 | ]) 38 | AC_CACHE_CHECK([for Perl CPPFLAGS],[pandora_cv_perl_cppflags],[ 39 | pandora_cv_perl_cppflags=`$PERL -MConfig -e 'print $Config{cppflags};'` 40 | pandora_cv_perl_cppflags="${pandora_cv_perl_cppflags}" 41 | ]) 42 | PERL_CPPFLAGS="-I${pandora_cv_perl_include} ${pandora_cv_perl_cppflags}" 43 | 44 | AC_CACHE_CHECK([for Perl development headers], 45 | [pandora_cv_perl_dev],[ 46 | 47 | save_CPPFLAGS="${CPPFLAGS}" 48 | CPPFLAGS="${CPPFLAGS} ${PERL_CPPFLAGS}" 49 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 50 | #include 51 | #include 52 | #include "EXTERN.h" 53 | #include "perl.h" 54 | #include "XSUB.h" 55 | ]])], 56 | [pandora_cv_perl_dev=yes], 57 | [pandora_cv_perl_dev=no]) 58 | CPPFLAGS="${save_CPPFLAGS}" 59 | ]) 60 | 61 | AS_IF([test "${pandora_cv_perl_dev}" = "no"], 62 | [with_perl=no]) 63 | 64 | AC_CACHE_CHECK([for Perl install location], 65 | [pandora_cv_perl_archdir],[ 66 | AS_IF([test "${with_perl_arch}" = "no"],[ 67 | pandora_cv_perl_archdir=`$PERL -MConfig -e 'print $Config{sitearch}'` 68 | ],[ 69 | pandora_cv_perl_archdir=`$PERL -MConfig -e 'print $Config{archlib}'` 70 | ]) 71 | pandora_cv_perl_archdir="${pandora_cv_perl_archdir}" 72 | ]) 73 | 74 | PERL_ARCHDIR="${pandora_cv_perl_archdir}" 75 | ]) 76 | AC_SUBST([PERL_CPPFLAGS]) 77 | AC_SUBST([PERL_ARCHDIR]) 78 | 79 | AM_CONDITIONAL(BUILD_PERL, [test "$with_perl" != "no"]) 80 | 81 | ]) 82 | -------------------------------------------------------------------------------- /m4/pandora_with_php.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | 13 | AC_DEFUN([PANDORA_WITH_PHP],[ 14 | 15 | AC_ARG_WITH([php], 16 | [AS_HELP_STRING([--with-php], 17 | [Build NDB/PHP @<:@default=no@:>@])], 18 | [with_php=$withval], 19 | [with_php=no]) 20 | 21 | AS_IF([test "x$with_php" != "xno"],[ 22 | dnl We explicitly requested PHP build. Fail on too-young SWIG. 23 | AS_IF([test "x$SWIG_CAN_BUILD_PHP" != "xyes"], 24 | [AC_MSG_ERROR("Your version of SWIG is too young to build NDB/PHP. >=1.3.33 is required!")]) 25 | AS_IF([test "x$with_php" != "xyes"], 26 | [ac_check_php_config=$with_php], 27 | [ac_check_php_config="php-config php-config5"]) 28 | AC_CHECK_PROGS(PHP_CONFIG, [$ac_check_php_config]) 29 | ]) 30 | 31 | AS_IF([test "x$PHP_CONFIG" != "x"],[ 32 | PHP_CFLAGS=`$PHP_CONFIG --includes` 33 | PHP_CPPFLAGS=`$PHP_CONFIG --includes` 34 | PHP_LDFLAGS=`$PHP_CONFIG --ldflags` 35 | PHP_EXTDIR=`$PHP_CONFIG --extension-dir` 36 | strip_php_prefix=`$PHP_CONFIG --prefix | sed 's/\//./g'` 37 | PHP_ARCH_DIR=`echo $PHP_EXTDIR | sed "s/$strip_php_prefix//"` 38 | ],[ 39 | PHP_CFLAGS= 40 | PHP_CPPFLAGS= 41 | PHP_LDFLAGS= 42 | PHP_EXTDIR= 43 | PHP_ARCH_DIR= 44 | with_php=no 45 | ]) 46 | 47 | AC_SUBST(PHP_CFLAGS) 48 | AC_SUBST(PHP_CPPFLAGS) 49 | AC_SUBST(PHP_LDFLAGS) 50 | AC_SUBST(PHP_EXTDIR) 51 | AC_SUBST(PHP_ARCH_DIR) 52 | 53 | AM_CONDITIONAL(BUILD_PHP, test "$with_php" = "yes") 54 | 55 | ]) 56 | 57 | -------------------------------------------------------------------------------- /m4/pandora_with_python.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | 13 | AC_DEFUN([PANDORA_WITH_PYTHON], [ 14 | 15 | AC_ARG_WITH([python], 16 | [AS_HELP_STRING([--with-python], 17 | [Build Python Bindings @<:@default=yes@:>@])], 18 | [with_python=$withval], 19 | [with_python=yes]) 20 | 21 | AS_IF([test "x$with_python" != "xno"],[ 22 | AS_IF([test "x$with_python" != "xyes"],[PYTHON=$with_python]) 23 | AM_PATH_PYTHON([2.4],,[with_python="no"]) 24 | AC_PYTHON_DEVEL() 25 | AS_IF([test "x$pythonexists" = "xno"],[with_python="no"]) 26 | ]) 27 | AM_CONDITIONAL(BUILD_PYTHON, [test "$with_python" = "yes"]) 28 | ]) 29 | -------------------------------------------------------------------------------- /m4/pandora_with_python3.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | AC_DEFUN([PANDORA_WITH_PYTHON3], [ 13 | 14 | AC_REQUIRE([PANDORA_SWIG]) 15 | 16 | AC_ARG_WITH([python3], 17 | [AS_HELP_STRING([--with-python3], 18 | [Build Python3 Bindings @<:@default=yes@:>@])],[ 19 | with_python3=$withval 20 | python3_requested=yes 21 | ],[ 22 | with_python3=yes 23 | python3_requested=no 24 | ]) 25 | 26 | AS_IF([test "x$ac_cv_swig_has_python3_" != "xyes"],[ 27 | with_python3=no 28 | ],[ 29 | AS_IF([test "x$with_python3" != "xno"],[ 30 | AS_IF([test "x$with_python3" != "xyes"], 31 | [PYTHON3=$with_python3],[ 32 | AC_PATH_PROG([PYTHON3],[python3],[no]) 33 | PANDORA_PYTHON3_DEVEL() 34 | AS_IF([test "x$python3exists" = "xno"],[with_python="no"]) 35 | ]) 36 | ]) 37 | ]) 38 | AS_IF([test "x$with_python3" = "xno" -a "$python3_requested" = "yes"],[ 39 | AC_MSG_ERROR([Python3 support was explicity requested, but Python3 support 40 | was not found. Please correct your build environment and try 41 | again]) 42 | ]) 43 | AM_CONDITIONAL(BUILD_PYTHON3, [test "$with_python3" = "yes"]) 44 | ]) 45 | -------------------------------------------------------------------------------- /m4/pandora_with_r.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | AC_DEFUN([PANDORA_WITH_R],[ 13 | dnl Check for GNU R 14 | AC_ARG_WITH([r], 15 | [AS_HELP_STRING([--with-r], 16 | [Build R Bindings @<:@default=yes@:>@])], 17 | [with_r=$withval], 18 | [with_r=yes]) 19 | 20 | AS_IF([test "x$with_r" != "xno"],[ 21 | 22 | PKG_CHECK_MODULES([R], [libR], [ 23 | with_r=yes 24 | ],[ 25 | with_r=no 26 | ]) 27 | 28 | AC_SUBST(R_CFLAGS) 29 | AC_SUBST(R_LIBS) 30 | ]) 31 | AM_CONDITIONAL(BUILD_R, test "$with_r" = "yes") 32 | 33 | ]) 34 | -------------------------------------------------------------------------------- /m4/pandora_with_ruby.m4: -------------------------------------------------------------------------------- 1 | dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 3 | dnl 4 | dnl pandora-build: A pedantic build system 5 | dnl Copyright (C) 2009 Sun Microsystems, Inc. 6 | dnl This file is free software; Sun Microsystems 7 | dnl gives unlimited permission to copy and/or distribute it, 8 | dnl with or without modifications, as long as this notice is preserved. 9 | dnl 10 | dnl From Monty Taylor 11 | 12 | 13 | AC_DEFUN([PANDORA_WITH_RUBY], [ 14 | 15 | AC_ARG_WITH([ruby], 16 | [AS_HELP_STRING([--with-ruby], 17 | [Build Ruby Bindings @<:@default=yes@:>@])], 18 | [with_ruby=$withval], 19 | [with_ruby=ruby]) 20 | 21 | AS_IF([test "x$with_ruby" != "xno"],[ 22 | AS_IF([test "x$with_ruby" != "xyes"], 23 | [ac_chk_ruby=$with_ruby], 24 | [ac_chk_ruby=ruby1.8 ruby]) 25 | AC_CHECK_PROGS(RUBY,$ac_chk_ruby) 26 | ]) 27 | 28 | AS_IF([test "x$RUBY" != "x"],[ 29 | 30 | AC_MSG_CHECKING(for ruby devel) 31 | 32 | dnl need to change quotes to allow square brackets 33 | changequote(<<, >>)dnl 34 | ruby_prefix=`$RUBY -rrbconfig -e "print Config::CONFIG['archdir']"` 35 | strip_ruby_prefix=`$RUBY -rrbconfig -e "print Config::CONFIG['prefix']" | sed 's/\//./g'` 36 | 37 | RUBY_LIB=`$RUBY -rrbconfig -e "puts Config::CONFIG['ruby_install_name']"` 38 | LIBRUBYARG_SHARED=`$RUBY -rrbconfig -e "puts Config::CONFIG['LIBRUBYARG_SHARED']"` 39 | RUBY_DIR=`$RUBY -rrbconfig -e "puts Config::CONFIG['archdir']"` 40 | RUBY_ARCH_DIR=`echo $RUBY_DIR | sed "s/$strip_ruby_prefix//"` 41 | RUBY_LIBDIR=`$RUBY -rrbconfig -e "puts Config::CONFIG['rubylibdir']"` 42 | RUBY_INCLUDES="-I$ruby_prefix" 43 | changequote([, ])dnl 44 | 45 | ac_save_CFLAGS="$CFLAGS" 46 | ac_save_CPPFLAGS="$CPPFLAGS" 47 | ac_save_LDFLAGS="$LDFLAGS" 48 | CFLAGS="$ac_save_CFLAGS $RUBY_INCLUDES" 49 | CPPFLAGS="$ac_save_CPPFLAGS $RUBY_INCLUDES" 50 | LDFLAGS="$ac_save_LDFLAGS $LIBRUBYARG_SHARED" 51 | 52 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[VALUE rb_ac_test = rb_define_module("actest");]])],[with_ruby="yes";AC_MSG_RESULT(found)],[with_ruby="no";AC_MSG_RESULT(missing)]) 53 | 54 | CPPFLAGS="$ac_save_CPPFLAGS" 55 | CFLAGS="$ac_save_CFLAGS" 56 | LDFLAGS="$ac_save_LDFLAGS" 57 | ],[ 58 | # This allows 'make clean' in the ruby directory to work when 59 | # ruby isn't available 60 | RUBY= 61 | RUBY_INCLUDES= 62 | LIBRUBYARG_SHARED= 63 | RUBY_LIB= 64 | RUBY_DIR= 65 | RUBY_LIBDIR= 66 | RUBY_ARCH_DIR= 67 | with_ruby="no" 68 | ]) 69 | 70 | AC_SUBST(RUBY_INCLUDES) 71 | AC_SUBST(LIBRUBYARG_SHARED) 72 | AC_SUBST(RUBY_LIB) 73 | AC_SUBST(RUBY_DIR) 74 | AC_SUBST(RUBY_LIBDIR) 75 | AC_SUBST(RUBY_ARCH_DIR) 76 | 77 | AS_IF([test "x$RUBY_DIR" = "x"],[with_ruby="no"]) 78 | AM_CONDITIONAL(BUILD_RUBY, test "$with_ruby" = "yes") 79 | ]) 80 | -------------------------------------------------------------------------------- /matcher.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | #ifndef MATCHER_H 4 | #define MATCHER_H 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct { 11 | // We have a simple implementation currently that 12 | // only supports simple string prefix matching, O(N^2). 13 | // 14 | pthread_mutex_t *lock; 15 | 16 | int patterns_max; // Size of patterns array, may be 0. 17 | int patterns_num; // Number of active patterns, <= patterns_max. 18 | char **patterns; // May be NULL. 19 | int *lengths; // May be NULL, same size as patterns array. 20 | 21 | // Statistics. 22 | // 23 | uint64_t *hits; // May be NULL, same size as patterns array. 24 | uint64_t misses; 25 | } matcher; 26 | 27 | void matcher_init(matcher *m, bool multithreaded); 28 | void matcher_start(matcher *m, char *spec); 29 | bool matcher_started(matcher *m); 30 | void matcher_stop(matcher *m); 31 | matcher *matcher_clone(matcher *m, matcher *copy); 32 | bool matcher_check(matcher *m, char *str, int str_len, 33 | bool default_when_unstarted); 34 | 35 | #endif /* MATCHER_H */ 36 | 37 | -------------------------------------------------------------------------------- /mcs.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | #ifndef MCS_H 4 | #define MCS_H 5 | 6 | #ifdef HAVE_CONFIG_H 7 | #include "config.h" 8 | #endif 9 | 10 | #ifdef WIN32 11 | #ifndef EINPROGRESS 12 | #define EINPROGRESS WSAEINPROGRESS 13 | #endif 14 | #ifndef EISCONN 15 | #define EISCONN WSAEISCONN 16 | #endif 17 | #endif 18 | 19 | // The mcs API's are a level of indirection from direct libmemcached 20 | // and libvbucket API usage. 21 | // 22 | typedef enum { 23 | MCS_SUCCESS = 0, 24 | MCS_FAILURE, 25 | MCS_MAXIMUM_RETURN /* Always add new error code before */ 26 | } mcs_return; 27 | 28 | typedef enum { 29 | MCS_KIND_UNKNOWN = 0, 30 | MCS_KIND_LIBVBUCKET, 31 | MCS_KIND_LIBMEMCACHED, 32 | MCS_KIND_MAX 33 | } mcs_kind; 34 | 35 | typedef struct { 36 | char hostname[200]; 37 | int port; 38 | int fd; 39 | char *usr; 40 | char *pwd; 41 | } mcs_server_st; 42 | 43 | typedef struct { 44 | mcs_kind kind; 45 | void *data; // Depends on kind. 46 | int nservers; // Size of servers array. 47 | mcs_server_st *servers; 48 | } mcs_st; 49 | 50 | mcs_st *mcs_create(mcs_st *ptr, const char *config); 51 | void mcs_free(mcs_st *ptr); 52 | 53 | bool mcs_stable_update(mcs_st *curr_version, mcs_st *next_version); 54 | 55 | uint32_t mcs_server_count(mcs_st *ptr); 56 | mcs_server_st *mcs_server_index(mcs_st *ptr, int i); 57 | 58 | uint32_t mcs_key_hash(mcs_st *ptr, const char *key, size_t key_length, int *vbucket); 59 | 60 | void mcs_server_invalid_vbucket(mcs_st *ptr, int server_index, int vbucket); 61 | 62 | void mcs_server_st_quit(mcs_server_st *ptr, uint8_t io_death); 63 | 64 | mcs_return mcs_server_st_connect(mcs_server_st *ptr, 65 | int *errno_out, 66 | bool blocking); 67 | 68 | ssize_t mcs_io_write(int fd, const void *buffer, size_t length); 69 | mcs_return mcs_io_read(int fd, void *dta, size_t size); 70 | void mcs_io_reset(int fd); 71 | 72 | const char *mcs_server_st_hostname(mcs_server_st *ptr); 73 | int mcs_server_st_port(mcs_server_st *ptr); 74 | int mcs_server_st_fd(mcs_server_st *ptr); 75 | const char *mcs_server_st_usr(mcs_server_st *ptr); 76 | const char *mcs_server_st_pwd(mcs_server_st *ptr); 77 | 78 | mcs_return mcs_set_sock_opt(int sock); 79 | 80 | int mcs_connect(const char *hostname, int portnum, 81 | int *errno_out, bool blocking); 82 | 83 | // ---------------------------------------- 84 | 85 | #define MOXI_DEFAULT_LISTEN_PORT 0 86 | #define MEMCACHED_DEFAULT_LISTEN_PORT 11210 87 | 88 | // ---------------------------------------- 89 | 90 | #ifdef MOXI_USE_LIBMEMCACHED 91 | 92 | #include 93 | 94 | #endif // MOXI_USE_LIBMEMCACHED 95 | 96 | // ---------------------------------------- 97 | 98 | #ifdef MOXI_USE_LIBVBUCKET 99 | 100 | #include 101 | 102 | #undef MOXI_DEFAULT_LISTEN_PORT 103 | #define MOXI_DEFAULT_LISTEN_PORT 11211 104 | 105 | #undef MEMCACHED_DEFAULT_LISTEN_PORT 106 | #define MEMCACHED_DEFAULT_LISTEN_PORT 0 107 | 108 | #endif // MOXI_USE_LIBVBUCKET 109 | 110 | #endif // MCS_H 111 | -------------------------------------------------------------------------------- /memcached.spec.in: -------------------------------------------------------------------------------- 1 | Name: memcached 2 | Version: @VERSION@ 3 | Release: 1%{?dist} 4 | Summary: High Performance, Distributed Memory Object Cache 5 | 6 | Group: System Environment/Daemons 7 | License: BSD 8 | URL: http://www.danga.com/memcached/ 9 | Source0: http://www.danga.com/memcached/dist/%{name}-%{version}.tar.gz 10 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 11 | 12 | BuildRequires: libevent-devel 13 | BuildRequires: perl(Test::More) 14 | Requires: initscripts 15 | Requires(post): /sbin/chkconfig 16 | Requires(preun): /sbin/chkconfig, /sbin/service 17 | Requires(postun): /sbin/service 18 | 19 | %description 20 | memcached is a high-performance, distributed memory object caching 21 | system, generic in nature, but intended for use in speeding up dynamic 22 | web applications by alleviating database load. 23 | 24 | %prep 25 | %setup -q 26 | 27 | 28 | %build 29 | %configure --enable-threads 30 | 31 | make %{?_smp_mflags} 32 | 33 | %check 34 | make test 35 | 36 | %install 37 | rm -rf %{buildroot} 38 | make install DESTDIR=%{buildroot} 39 | 40 | # remove memcached-debug 41 | rm -f %{buildroot}/%{_bindir}/memcached-debug 42 | 43 | # Perl script for monitoring memcached 44 | install -Dp -m0755 scripts/memcached-tool %{buildroot}%{_bindir}/memcached-tool 45 | 46 | # Init script 47 | install -Dp -m0755 scripts/memcached.sysv %{buildroot}%{_initrddir}/memcached 48 | 49 | # Default configs 50 | mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig 51 | cat <%{buildroot}/%{_sysconfdir}/sysconfig/%{name} 52 | PORT="11211" 53 | USER="nobody" 54 | MAXCONN="1024" 55 | CACHESIZE="64" 56 | OPTIONS="" 57 | EOF 58 | 59 | # pid directory 60 | mkdir -p %{buildroot}/%{_localstatedir}/run/memcached 61 | 62 | %clean 63 | rm -rf %{buildroot} 64 | 65 | 66 | %post 67 | /sbin/chkconfig --add %{name} 68 | 69 | %preun 70 | if [ "$1" = 0 ] ; then 71 | /sbin/service %{name} stop > /dev/null 2>&1 72 | /sbin/chkconfig --del %{name} 73 | fi 74 | exit 0 75 | 76 | %postun 77 | if [ "$1" -ge 1 ]; then 78 | /sbin/service %{name} condrestart > /dev/null 2>&1 79 | fi 80 | exit 0 81 | 82 | 83 | %files 84 | %defattr(-,root,root,-) 85 | %doc AUTHORS ChangeLog COPYING NEWS README TODO doc/CONTRIBUTORS doc/*.txt 86 | %config(noreplace) %{_sysconfdir}/sysconfig/%{name} 87 | 88 | %dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached 89 | %{_bindir}/memcached-tool 90 | %{_bindir}/memcached 91 | %{_mandir}/man1/memcached.1* 92 | %{_initrddir}/memcached 93 | %{_includedir}/memcached 94 | 95 | %changelog 96 | * Sat Aug 29 2009 Dustin Sallings - 1.4.1-1 97 | - Autogenerate the version number from tags. 98 | 99 | * Wed Jul 4 2007 Paul Lindner - 1.2.2-5 100 | - Use /var/run/memcached/ directory to hold PID file 101 | 102 | * Sat May 12 2007 Paul Lindner - 1.2.2-4 103 | - Remove tabs from spec file, rpmlint reports no more errors 104 | 105 | * Thu May 10 2007 Paul Lindner - 1.2.2-3 106 | - Enable build-time regression tests 107 | - add dependency on initscripts 108 | - remove memcached-debug (not needed in dist) 109 | - above suggestions from Bernard Johnson 110 | 111 | * Mon May 7 2007 Paul Lindner - 1.2.2-2 112 | - Tidyness improvements suggested by Ruben Kerkhof in bugzilla #238994 113 | 114 | * Fri May 4 2007 Paul Lindner - 1.2.2-1 115 | - Initial spec file created via rpmdev-newspec 116 | -------------------------------------------------------------------------------- /murmur_hash.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | "Murmur" hash provided by Austin, tanjent@gmail.com 9 | http://murmurhash.googlepages.com/ 10 | 11 | Note - This code makes a few assumptions about how your machine behaves - 12 | 13 | 1. We can read a 4-byte value from any address without crashing 14 | 2. sizeof(int) == 4 15 | 16 | And it has a few limitations - 17 | 1. It will not work incrementally. 18 | 2. It will not produce the same results on little-endian and big-endian 19 | machines. 20 | 21 | Updated to murmur2 hash - BP 22 | */ 23 | 24 | uint32_t murmur_hash(const char *key, size_t length); 25 | 26 | uint32_t murmur_hash(const char *key, size_t length) 27 | { 28 | /* 29 | 'm' and 'r' are mixing constants generated offline. They're not 30 | really 'magic', they just happen to work well. 31 | */ 32 | 33 | const unsigned int m= 0x5bd1e995; 34 | const unsigned int seed= (0xdeadbeef * length); 35 | const int r= 24; 36 | 37 | 38 | // Initialize the hash to a 'random' value 39 | 40 | unsigned int h= seed ^ length; 41 | 42 | // Mix 4 bytes at a time into the hash 43 | 44 | const unsigned char * data= (const unsigned char *)key; 45 | 46 | while(length >= 4) 47 | { 48 | unsigned int k = *(unsigned int *)data; 49 | 50 | k *= m; 51 | k ^= k >> r; 52 | k *= m; 53 | 54 | h *= m; 55 | h ^= k; 56 | 57 | data += 4; 58 | length -= 4; 59 | } 60 | 61 | // Handle the last few bytes of the input array 62 | 63 | switch(length) 64 | { 65 | case 3: h ^= data[2] << 16; 66 | case 2: h ^= data[1] << 8; 67 | case 1: h ^= data[0]; 68 | h *= m; 69 | }; 70 | 71 | /* 72 | Do a few final mixes of the hash to ensure the last few bytes are 73 | well-incorporated. 74 | */ 75 | 76 | h ^= h >> 13; 77 | h *= m; 78 | h ^= h >> 15; 79 | 80 | return h; 81 | } 82 | -------------------------------------------------------------------------------- /redirects.c: -------------------------------------------------------------------------------- 1 | #include "redirects.h" 2 | 3 | #ifdef HAVE_CONFLATE_H 4 | 5 | #undef conflate_add_field 6 | #undef conflate_add_field_multi 7 | #undef conflate_next_fieldset 8 | #undef conflate_init_form 9 | 10 | void (*redirected_conflate_add_field_target)(conflate_form_result *r, const char *k, const char *v) = conflate_add_field; 11 | void (*redirected_conflate_add_field_multi_target)(conflate_form_result *r, const char *k, const char **v) = conflate_add_field_multi; 12 | void (*redirected_conflate_next_fieldset_target)(conflate_form_result *r) = conflate_next_fieldset; 13 | void (*redirected_conflate_init_form_target)(conflate_form_result *r) = conflate_init_form; 14 | 15 | #endif 16 | 17 | #undef collect_memcached_stats_for_proxy 18 | 19 | void (*redirected_collect_memcached_stats_for_proxy_target)(struct main_stats_collect_info *msci, 20 | const char *proxy_name, 21 | int proxy_port) = collect_memcached_stats_for_proxy; 22 | void redirected_collect_memcached_stats_for_proxy(struct main_stats_collect_info *msci, 23 | const char *proxy_name, 24 | int proxy_port) 25 | { 26 | (*redirected_collect_memcached_stats_for_proxy_target)(msci, proxy_name, proxy_port); 27 | } 28 | 29 | void reset_redirections(void) 30 | { 31 | redirected_collect_memcached_stats_for_proxy_target = collect_memcached_stats_for_proxy; 32 | #ifdef HAVE_CONFLATE_H 33 | redirected_conflate_add_field_target = conflate_add_field; 34 | redirected_conflate_add_field_multi_target = conflate_add_field_multi; 35 | redirected_conflate_next_fieldset_target = conflate_next_fieldset; 36 | redirected_conflate_init_form_target = conflate_init_form; 37 | #endif 38 | } 39 | 40 | #ifdef HAVE_CONFLATE_H 41 | void redirected_conflate_add_field(conflate_form_result *r, const char *k, const char *v) 42 | { 43 | (*redirected_conflate_add_field_target)(r,k,v); 44 | } 45 | 46 | void redirected_conflate_add_field_multi(conflate_form_result *r, const char *k, const char **v) 47 | { 48 | (*redirected_conflate_add_field_multi_target)(r,k,v); 49 | } 50 | 51 | void redirected_conflate_next_fieldset(conflate_form_result *r) 52 | { 53 | (*redirected_conflate_next_fieldset_target)(r); 54 | } 55 | 56 | void redirected_conflate_init_form(conflate_form_result *r) 57 | { 58 | (*redirected_conflate_init_form_target)(r); 59 | } 60 | #endif 61 | -------------------------------------------------------------------------------- /redirects.h: -------------------------------------------------------------------------------- 1 | #ifndef REDIRECTS_H 2 | #define REDIRECTS_H 3 | #include "config.h" 4 | 5 | #ifdef HAVE_CONFLATE_H 6 | #include 7 | 8 | #define conflate_add_field redirected_conflate_add_field 9 | #define conflate_add_field_multi redirected_conflate_add_field_multi 10 | #define conflate_next_fieldset redirected_conflate_next_fieldset 11 | #define conflate_init_form redirected_conflate_init_form 12 | 13 | extern void (*redirected_conflate_add_field_target)(conflate_form_result *r, const char *k, const char *v); 14 | extern void (*redirected_conflate_add_field_multi_target)(conflate_form_result *r, const char *k, const char **v); 15 | extern void (*redirected_conflate_next_fieldset_target)(conflate_form_result *r); 16 | extern void (*redirected_conflate_init_form_target)(conflate_form_result *r); 17 | 18 | void redirected_conflate_add_field(conflate_form_result *r, const char *k, const char *v); 19 | void redirected_conflate_add_field_multi(conflate_form_result *r, const char *k, const char **v); 20 | void redirected_conflate_next_fieldset(conflate_form_result *r); 21 | void redirected_conflate_init_form(conflate_form_result *r); 22 | 23 | #endif // HAVE_CONFLATE_H 24 | 25 | struct main_stats_collect_info; 26 | 27 | void collect_memcached_stats_for_proxy(struct main_stats_collect_info *msci, const char *proxy_name, int proxy_port); 28 | void redirected_collect_memcached_stats_for_proxy(struct main_stats_collect_info *msci, const char *proxy_name, int proxy_port); 29 | extern void (*redirected_collect_memcached_stats_for_proxy_target)(struct main_stats_collect_info *msci, const char *proxy_name, int proxy_port); 30 | 31 | #define collect_memcached_stats_for_proxy redirected_collect_memcached_stats_for_proxy 32 | 33 | void reset_redirections(void); 34 | 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /scripts/examples/moxi.conf.direct: -------------------------------------------------------------------------------- 1 | 11211=memcached1.yourcorp.com:11211,memcached2.yourcorp.com:11211 2 | -------------------------------------------------------------------------------- /scripts/examples/moxi.conf.service: -------------------------------------------------------------------------------- 1 | apikey=my_user_id:my_password@memscale.ec2.northscale.net 2 | -------------------------------------------------------------------------------- /scripts/memcached-init: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # skeleton example file to build /etc/init.d/ scripts. 4 | # This file should be used to construct scripts for /etc/init.d. 5 | # 6 | # Written by Miquel van Smoorenburg . 7 | # Modified for Debian 8 | # by Ian Murdock . 9 | # 10 | # Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl 11 | # 12 | 13 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 14 | DAEMON=/usr/bin/memcached 15 | DAEMONBOOTSTRAP=/usr/share/memcached/scripts/start-memcached 16 | NAME=memcached 17 | DESC=memcached 18 | PIDFILE=/var/run/$NAME.pid 19 | 20 | test -x $DAEMON || exit 0 21 | test -x $DAEMONBOOTSTRAP || exit 0 22 | 23 | set -e 24 | 25 | case "$1" in 26 | start) 27 | echo -n "Starting $DESC: " 28 | start-stop-daemon --start --quiet --exec $DAEMONBOOTSTRAP 29 | echo "$NAME." 30 | ;; 31 | stop) 32 | echo -n "Stopping $DESC: " 33 | start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON 34 | echo "$NAME." 35 | rm -f $PIDFILE 36 | ;; 37 | 38 | restart|force-reload) 39 | # 40 | # If the "reload" option is implemented, move the "force-reload" 41 | # option to the "reload" entry above. If not, "force-reload" is 42 | # just the same as "restart". 43 | # 44 | echo -n "Restarting $DESC: " 45 | start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE 46 | rm -f $PIDFILE 47 | sleep 1 48 | start-stop-daemon --start --quiet --exec $DAEMONBOOTSTRAP 49 | echo "$NAME." 50 | ;; 51 | *) 52 | N=/etc/init.d/$NAME 53 | # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 54 | echo "Usage: $N {start|stop|restart|force-reload}" >&2 55 | exit 1 56 | ;; 57 | esac 58 | 59 | exit 0 60 | -------------------------------------------------------------------------------- /scripts/memcached.sysv: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # chkconfig: - 55 45 4 | # description: The memcached daemon is a network memory cache service. 5 | # processname: memcached 6 | # config: /etc/sysconfig/memcached 7 | 8 | # Source function library. 9 | . /etc/rc.d/init.d/functions 10 | 11 | PORT=11211 12 | USER=nobody 13 | MAXCONN=1024 14 | CACHESIZE=64 15 | OPTIONS="" 16 | 17 | if [ -f /etc/sysconfig/memcached ];then 18 | . /etc/sysconfig/memcached 19 | fi 20 | 21 | # Check that networking is up. 22 | if [ "$NETWORKING" = "no" ] 23 | then 24 | exit 0 25 | fi 26 | 27 | RETVAL=0 28 | prog="memcached" 29 | 30 | start () { 31 | echo -n $"Starting $prog: " 32 | # insure that /var/run/memcached has proper permissions 33 | chown $USER /var/run/memcached 34 | daemon memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached/memcached.pid $OPTIONS 35 | RETVAL=$? 36 | echo 37 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached 38 | } 39 | stop () { 40 | echo -n $"Stopping $prog: " 41 | killproc memcached 42 | RETVAL=$? 43 | echo 44 | if [ $RETVAL -eq 0 ] ; then 45 | rm -f /var/lock/subsys/memcached 46 | rm -f /var/run/memcached.pid 47 | fi 48 | } 49 | 50 | restart () { 51 | stop 52 | start 53 | } 54 | 55 | 56 | # See how we were called. 57 | case "$1" in 58 | start) 59 | start 60 | ;; 61 | stop) 62 | stop 63 | ;; 64 | status) 65 | status memcached 66 | ;; 67 | restart|reload) 68 | restart 69 | ;; 70 | condrestart) 71 | [ -f /var/lock/subsys/memcached ] && restart || : 72 | ;; 73 | *) 74 | echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" 75 | exit 1 76 | esac 77 | 78 | exit $? 79 | -------------------------------------------------------------------------------- /scripts/moxi-init.rhat.in: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # chkconfig: - 55 45 4 | # description: The moxi is a memchached proxy 5 | # processname: moxi 6 | # config: /etc/sysconfig/moxi 7 | 8 | # Source function library. 9 | . /etc/rc.d/init.d/functions 10 | 11 | USER=nobody 12 | MAXCONN=1024 13 | CPROXY_ARG=/etc/moxi.conf 14 | OPTIONS="" 15 | 16 | if [ -f /etc/sysconfig/moxi ];then 17 | . /etc/sysconfig/moxi 18 | fi 19 | 20 | # Check that networking is up. 21 | if [ "$NETWORKING" = "no" ] 22 | then 23 | exit 0 24 | fi 25 | 26 | # if CPROXY_ARG is a config file reference check it's existance 27 | if ([[ "/" < "$CPROXY_ARG" ]] && [[ "$CPROXY_ARG" < "0" ]]) || ([[ "." < "$CPROXY_ARG" ]] && [[ "$CPROXY_ARG" < "/" ]]); then 28 | if [ ! -f "$CPROXY_ARG" ]; then 29 | echo "Misconfiguration! '$CPROXY_ARG' is absent. See /usr/share/doc/moxi-%{version}/examples/ for configuration examples. Aborting." 30 | exit 1 31 | fi 32 | fi 33 | 34 | RETVAL=0 35 | prog="moxi" 36 | 37 | start () { 38 | echo -n $"Starting $prog: " 39 | # insure that /var/run/moxi has proper permissions 40 | chown $USER /var/run/moxi 41 | daemon /usr/bin/moxi -d -u $USER -c $MAXCONN -z $CPROXY_ARG -P /var/run/moxi/moxi.pid $OPTIONS 42 | RETVAL=$? 43 | echo 44 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/moxi 45 | } 46 | stop () { 47 | echo -n $"Stopping $prog: " 48 | killproc moxi 49 | RETVAL=$? 50 | echo 51 | if [ $RETVAL -eq 0 ] ; then 52 | rm -f /var/lock/subsys/moxi 53 | rm -f /var/run/moxi.pid 54 | fi 55 | } 56 | 57 | restart () { 58 | stop 59 | start 60 | } 61 | 62 | 63 | # See how we were called. 64 | case "$1" in 65 | start) 66 | start 67 | ;; 68 | stop) 69 | stop 70 | ;; 71 | status) 72 | status moxi 73 | ;; 74 | restart|reload) 75 | restart 76 | ;; 77 | condrestart) 78 | [ -f /var/lock/subsys/moxi ] && restart || : 79 | ;; 80 | *) 81 | echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" 82 | exit 1 83 | esac 84 | 85 | exit $? 86 | -------------------------------------------------------------------------------- /scripts/rpm/build-fc-rpm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf tmp/rpmbuild 4 | mkdir -p tmp/rpmbuild/SOURCES 5 | mkdir -p tmp/rpmbuild/BUILD 6 | mkdir -p tmp/rpmbuild/BUILDROOT 7 | mkdir -p tmp/rpmbuild/RPMS 8 | mkdir -p tmp/rpmbuild/SRPMS 9 | mkdir -p tmp/rpmbuild/SPECS 10 | 11 | rm -rf tmp/build 12 | mkdir tmp/build 13 | 14 | cp -R . tmp/build && \ 15 | tar cf tmp/rpmbuild/SOURCES/proxybuild.tar -C tmp proxybuild && \ 16 | rpmbuild --define="_topdir `pwd`/tmp/rpmbuild" -ba moxi.spec && \ 17 | cp tmp/rpmbuild/RPMS/*/*.rpm . 18 | -------------------------------------------------------------------------------- /scripts/rpm/moxi.spec.in: -------------------------------------------------------------------------------- 1 | Name: moxi 2 | Version: @VERSION@ 3 | Release: 1%{?dist} 4 | Summary: a memcached proxy with energy and pep 5 | Group: System Environment/Daemons 6 | License: BSD 7 | URL: http://northscale.com 8 | Source0: http://northscale.com/moxi/dist/%{name}-%{version}.tar.gz 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 10 | 11 | BuildRequires: automake 12 | BuildRequires: autoconf 13 | BuildRequires: libtool 14 | BuildRequires: openssl-devel 15 | BuildRequires: libevent-devel 16 | BuildRequires: pkgconfig 17 | BuildRequires: sqlite-devel 18 | BuildRequires: check-devel 19 | Requires: openssl 20 | Requires: libevent 21 | Requires: sqlite 22 | 23 | 24 | %description 25 | moxi is a memcached proxy with several optimizations to bring efficiency to 26 | many memcached deployments, especially those with heavy workloads or 27 | complex network topologies. Optimizations include handling timeouts for 28 | the client, deduplication of requests, a 'front' cache and protocol 29 | (ascii to binary) conversion. These optimizations keep the 'contract' 30 | of the memcached protocol whole for clients. 31 | 32 | %prep 33 | %setup -q 34 | 35 | %build 36 | CONFLATE_DB_PATH=/var/lib/moxi %configure --disable-coverage --disable-debug --disable-shared --without-memcached --with-bundled-libstrophe --with-libconflate=bundled 37 | 38 | make %{?_smp_mflags} 39 | 40 | 41 | %install 42 | rm -rf %{buildroot} 43 | make install DESTDIR="%{buildroot}" AM_INSTALL_PROGRAM_FLAGS="" 44 | # don't include libs and headers for conflate & strophe 45 | rm -rf %{buildroot}/usr/lib 46 | rm -rf %{buildroot}/usr/include 47 | 48 | # Init script 49 | sed -e 's/%%{version}/%{version}/g' < scripts/moxi-init.rhat.in > scripts/moxi-init.rhat 50 | install -Dp -m0755 scripts/moxi-init.rhat %{buildroot}%{_initrddir}/moxi 51 | # Default configs 52 | mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig 53 | cat <%{buildroot}/%{_sysconfdir}/sysconfig/%{name} 54 | USER="nobody" 55 | MAXCONN="1024" 56 | CPROXY_ARG="/etc/moxi.conf" 57 | OPTIONS="" 58 | EOF 59 | 60 | # pid directory 61 | mkdir -p %{buildroot}/%{_localstatedir}/run/moxi 62 | mkdir -p %{buildroot}/%{_localstatedir}/lib/moxi 63 | 64 | %clean 65 | rm -rf %{buildroot} 66 | 67 | %files 68 | %defattr(-,root,root,-) 69 | %doc AUTHORS COPYING README doc/CONTRIBUTORS scripts/examples/ 70 | %doc /usr/share/man/man1/moxi.1.gz 71 | %config(noreplace) %{_sysconfdir}/sysconfig/%{name} 72 | %dir %attr(750,nobody,nobody) %{_localstatedir}/run/moxi 73 | %dir %attr(750,nobody,nobody) %{_localstatedir}/lib/moxi 74 | %{_bindir}/moxi 75 | %{_initrddir}/moxi 76 | 77 | %changelog 78 | * Tue Jul 28 2009 Aliaksey Kandratsenka 79 | - packaged documentation and config-file examples 80 | * Mon Jul 27 2009 Aliaksey Kandratsenka 81 | - startup script 82 | * Fri Jul 17 2009 Matt Ingenthron 83 | - Updated install locations and removed memcached dependency 84 | * Fri Jul 17 2009 Aliaksey Kandratsenka 85 | - initial 86 | -------------------------------------------------------------------------------- /scripts/start-memcached: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # start-memcached 4 | # 2003/2004 - Jay Bonci 5 | # This script handles the parsing of the /etc/memcached.conf file 6 | # and was originally created for the Debian distribution. 7 | # Anyone may use this little script under the same terms as 8 | # memcached itself. 9 | 10 | use strict; 11 | 12 | if($> != 0 and $< != 0) 13 | { 14 | print STDERR "Only root wants to run start-memcached.\n"; 15 | exit; 16 | } 17 | 18 | my $params; my $etchandle; my $etcfile = "/etc/memcached.conf"; 19 | 20 | # This script assumes that memcached is located at /usr/bin/memcached, and 21 | # that the pidfile is writable at /var/run/memcached.pid 22 | 23 | my $memcached = "/usr/bin/memcached"; 24 | my $pidfile = "/var/run/memcached.pid"; 25 | 26 | # If we don't get a valid logfile parameter in the /etc/memcached.conf file, 27 | # we'll just throw away all of our in-daemon output. We need to re-tie it so 28 | # that non-bash shells will not hang on logout. Thanks to Michael Renner for 29 | # the tip 30 | my $fd_reopened = "/dev/null"; 31 | 32 | sub handle_logfile 33 | { 34 | my ($logfile) = @_; 35 | $fd_reopened = $logfile; 36 | } 37 | 38 | sub reopen_logfile 39 | { 40 | my ($logfile) = @_; 41 | 42 | open *STDERR, ">>$logfile"; 43 | open *STDOUT, ">>$logfile"; 44 | open *STDIN, ">>/dev/null"; 45 | $fd_reopened = $logfile; 46 | } 47 | 48 | # This is set up in place here to support other non -[a-z] directives 49 | 50 | my $conf_directives = { 51 | "logfile" => \&handle_logfile, 52 | }; 53 | 54 | if(open $etchandle, $etcfile) 55 | { 56 | foreach my $line (<$etchandle>) 57 | { 58 | $line ||= ""; 59 | $line =~ s/\#.*//g; 60 | $line =~ s/\s+$//g; 61 | $line =~ s/^\s+//g; 62 | next unless $line; 63 | next if $line =~ /^\-[dh]/; 64 | 65 | if($line =~ /^[^\-]/) 66 | { 67 | my ($directive, $arg) = $line =~ /^(.*?)\s+(.*)/; 68 | $conf_directives->{$directive}->($arg); 69 | next; 70 | } 71 | 72 | push @$params, $line; 73 | } 74 | 75 | }else{ 76 | $params = []; 77 | } 78 | 79 | push @$params, "-u root" unless(grep "-u", @$params); 80 | $params = join " ", @$params; 81 | 82 | if(-e $pidfile) 83 | { 84 | open PIDHANDLE, "$pidfile"; 85 | my $localpid = ; 86 | close PIDHANDLE; 87 | 88 | chomp $localpid; 89 | if(-d "/proc/$localpid") 90 | { 91 | print STDERR "memcached is already running.\n"; 92 | exit; 93 | }else{ 94 | `rm -f $localpid`; 95 | } 96 | 97 | } 98 | 99 | my $pid = fork(); 100 | 101 | if($pid == 0) 102 | { 103 | reopen_logfile($fd_reopened); 104 | exec "$memcached $params"; 105 | exit(0); 106 | 107 | }else{ 108 | if(open PIDHANDLE,">$pidfile") 109 | { 110 | print PIDHANDLE $pid; 111 | close PIDHANDLE; 112 | }else{ 113 | 114 | print STDERR "Can't write pidfile to $pidfile.\n"; 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /sizes.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | 4 | #include "memcached.h" 5 | 6 | static void display(const char *name, size_t size) { 7 | printf("%s\t%d\n", name, (int)size); 8 | } 9 | 10 | int main(void) { 11 | 12 | display("Slab Stats", sizeof(struct slab_stats)); 13 | display("Thread stats", 14 | sizeof(struct thread_stats) 15 | - (200 * sizeof(struct slab_stats))); 16 | display("Global stats", sizeof(struct stats)); 17 | display("Settings", sizeof(struct settings)); 18 | display("Item (no cas)", sizeof(item)); 19 | display("Item (cas)", sizeof(item) + sizeof(uint64_t)); 20 | display("Libevent thread", 21 | sizeof(LIBEVENT_THREAD) - sizeof(struct thread_stats)); 22 | display("Connection", sizeof(conn)); 23 | 24 | printf("----------------------------------------\n"); 25 | 26 | display("libevent thread cumulative", sizeof(LIBEVENT_THREAD)); 27 | display("Thread stats cumulative\t", sizeof(struct thread_stats)); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /slabs.h: -------------------------------------------------------------------------------- 1 | /* slabs memory allocation */ 2 | #ifndef SLABS_H 3 | #define SLABS_H 4 | 5 | /** Init the subsystem. 1st argument is the limit on no. of bytes to allocate, 6 | 0 if no limit. 2nd argument is the growth factor; each slab will use a chunk 7 | size equal to the previous slab's chunk size times this factor. 8 | 3rd argument specifies if the slab allocator should allocate all memory 9 | up front (if true), or allocate memory in chunks as it is needed (if false) 10 | */ 11 | void slabs_init(const size_t limit, const double factor, const bool prealloc); 12 | 13 | 14 | /** 15 | * Given object size, return id to use when allocating/freeing memory for object 16 | * 0 means error: can't store such a large object 17 | */ 18 | 19 | unsigned int slabs_clsid(const size_t size); 20 | 21 | /** Allocate object of given length. 0 on error */ /*@null@*/ 22 | void *slabs_alloc(const size_t size, unsigned int id); 23 | 24 | /** Free previously allocated object */ 25 | void slabs_free(void *ptr, size_t size, unsigned int id); 26 | 27 | /** Return a datum for stats in binary protocol */ 28 | bool get_stats(const char *stat_type, int nkey, ADD_STAT add_stats, void *c); 29 | 30 | /** Fill buffer with stats */ /*@null@*/ 31 | void slabs_stats(ADD_STAT add_stats, void *c); 32 | 33 | /* Request some slab be moved between classes 34 | 1 = success 35 | 0 = fail 36 | -1 = tried. busy. send again shortly. */ 37 | int slabs_reassign(unsigned char srcid, unsigned char dstid); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /solaris_priv.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | #include 5 | #include "memcached.h" 6 | 7 | /* 8 | * this section of code will drop all (Solaris) privileges including 9 | * those normally granted to all userland process (basic privileges). The 10 | * effect of this is that after running this code, the process will not able 11 | * to fork(), exec(), etc. See privileges(5) for more information. 12 | */ 13 | void drop_privileges(void) { 14 | priv_set_t *privs = priv_str_to_set("basic", ",", NULL); 15 | 16 | if (privs == NULL) { 17 | perror("priv_str_to_set"); 18 | exit(EXIT_FAILURE); 19 | } 20 | 21 | (void)priv_delset(privs, PRIV_FILE_LINK_ANY); 22 | (void)priv_delset(privs, PRIV_PROC_EXEC); 23 | (void)priv_delset(privs, PRIV_PROC_FORK); 24 | (void)priv_delset(privs, PRIV_PROC_INFO); 25 | (void)priv_delset(privs, PRIV_PROC_SESSION); 26 | 27 | if (setppriv(PRIV_SET, PRIV_PERMITTED, privs) != 0) { 28 | perror("setppriv(PRIV_SET, PRIV_PERMITTED)"); 29 | exit(EXIT_FAILURE); 30 | } 31 | 32 | priv_emptyset(privs); 33 | 34 | if (setppriv(PRIV_SET, PRIV_INHERITABLE, privs) != 0) { 35 | perror("setppriv(PRIV_SET, PRIV_INHERITABLE)"); 36 | exit(EXIT_FAILURE); 37 | } 38 | 39 | if (setppriv(PRIV_SET, PRIV_LIMIT, privs) != 0) { 40 | perror("setppriv(PRIV_SET, PRIV_LIMIT)"); 41 | exit(EXIT_FAILURE); 42 | } 43 | 44 | priv_freeset(privs); 45 | } 46 | -------------------------------------------------------------------------------- /stats.h: -------------------------------------------------------------------------------- 1 | /* stats */ 2 | void stats_prefix_init(void); 3 | void stats_prefix_clear(void); 4 | void stats_prefix_record_get(const char *key, const size_t nkey, const bool is_hit); 5 | void stats_prefix_record_delete(const char *key, const size_t nkey); 6 | void stats_prefix_record_set(const char *key, const size_t nkey); 7 | /*@null@*/ 8 | char *stats_prefix_dump(int *length); 9 | -------------------------------------------------------------------------------- /stdin_check.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | #include "config.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #include "stdin_check.h" 8 | #include "log.h" 9 | 10 | static void* check_stdin_thread(void* arg) 11 | { 12 | (void)arg; 13 | pthread_detach(pthread_self()); 14 | 15 | while (!feof(stdin)) { 16 | getc(stdin); 17 | } 18 | 19 | moxi_log_write("EOF on stdin. Exiting\n"); 20 | exit(0); 21 | /* NOTREACHED */ 22 | return NULL; 23 | } 24 | 25 | int stdin_check(void) { 26 | pthread_t t; 27 | if (pthread_create(&t, NULL, check_stdin_thread, NULL) != 0) { 28 | perror("couldn't create stdin checking thread."); 29 | return -1; 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /stdin_check.h: -------------------------------------------------------------------------------- 1 | #ifndef STDIN_CHECK_H 2 | #define STDIN_CHECK_H 3 | 4 | int stdin_check(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /t/00-startup.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 17; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | eval { 10 | my $server = new_memcached(); 11 | ok($server, "started the server"); 12 | }; 13 | is($@, '', 'Basic startup works'); 14 | 15 | eval { 16 | my $server = new_memcached("-l fooble"); 17 | }; 18 | ok($@, "Died with illegal -l args"); 19 | 20 | eval { 21 | my $server = new_memcached("-l 127.0.0.1"); 22 | }; 23 | is($@,'', "-l 127.0.0.1 works"); 24 | 25 | eval { 26 | my $server = new_memcached('-C'); 27 | my $stats = mem_stats($server->sock, 'settings'); 28 | is('no', $stats->{'cas_enabled'}); 29 | }; 30 | is($@, '', "-C works"); 31 | 32 | eval { 33 | my $server = new_memcached('-b 8675'); 34 | my $stats = mem_stats($server->sock, 'settings'); 35 | is('8675', $stats->{'tcp_backlog'}); 36 | }; 37 | is($@, '', "-b works"); 38 | 39 | foreach my $val ('auto', 'ascii') { 40 | eval { 41 | my $server = new_memcached("-B $val"); 42 | my $stats = mem_stats($server->sock, 'settings'); 43 | ok($stats->{'binding_protocol'} =~ /$val/, "$val works"); 44 | }; 45 | is($@, '', "$val works"); 46 | } 47 | 48 | # For the binary test, we just verify it starts since we don't have an easy bin client. 49 | eval { 50 | my $server = new_memcached("-B binary"); 51 | }; 52 | is($@, '', "binary works"); 53 | 54 | eval { 55 | my $server = new_memcached("-vv -B auto"); 56 | }; 57 | is($@, '', "auto works"); 58 | 59 | eval { 60 | my $server = new_memcached("-vv -B ascii"); 61 | }; 62 | is($@, '', "ascii works"); 63 | 64 | 65 | # For the binary test, we just verify it starts since we don't have an easy bin client. 66 | eval { 67 | my $server = new_memcached("-vv -B binary"); 68 | }; 69 | is($@, '', "binary works"); 70 | 71 | 72 | # Should blow up with something invalid. 73 | eval { 74 | my $server = new_memcached("-B http"); 75 | }; 76 | ok($@, "Died with illegal -B arg."); 77 | -------------------------------------------------------------------------------- /t/64bit.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | $ENV{T_MEMD_INITIAL_MALLOC} = "4294967328"; # 2**32 + 32 , just over 4GB 10 | $ENV{T_MEMD_SLABS_ALLOC} = 0; # don't preallocate slabs 11 | 12 | my $server = new_memcached("-m 4098 -M"); 13 | my $sock = $server->sock; 14 | 15 | my ($stats, $slabs) = @_; 16 | 17 | $stats = mem_stats($sock); 18 | 19 | if ($stats->{'pointer_size'} eq "32") { 20 | plan skip_all => 'Skipping 64-bit tests on 32-bit build'; 21 | exit 0; 22 | } else { 23 | plan tests => 6; 24 | } 25 | 26 | is($stats->{'pointer_size'}, 64, "is 64 bit"); 27 | is($stats->{'limit_maxbytes'}, "4297064448", "max bytes is 4098 MB"); 28 | 29 | $slabs = mem_stats($sock, 'slabs'); 30 | is($slabs->{'total_malloced'}, "4294967328", "expected (faked) value of total_malloced"); 31 | is($slabs->{'active_slabs'}, 0, "no active slabs"); 32 | 33 | my $hit_limit = 0; 34 | for (1..5) { 35 | my $size = 400 * 1024; 36 | my $data = "a" x $size; 37 | print $sock "set big$_ 0 0 $size\r\n$data\r\n"; 38 | my $res = <$sock>; 39 | $hit_limit = 1 if $res ne "STORED\r\n"; 40 | } 41 | ok($hit_limit, "hit size limit"); 42 | 43 | $slabs = mem_stats($sock, 'slabs'); 44 | is($slabs->{'active_slabs'}, 1, "1 active slab"); 45 | -------------------------------------------------------------------------------- /t/binary-get.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 8; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | my $count = 1; 13 | 14 | foreach my $blob ("mooo\0", "mumble\0\0\0\0\r\rblarg", "\0", "\r") { 15 | my $key = "foo$count"; 16 | my $len = length($blob); 17 | print "len is $len\n"; 18 | print $sock "set $key 0 0 $len\r\n$blob\r\n"; 19 | is(scalar <$sock>, "STORED\r\n", "stored $key"); 20 | mem_get_is($sock, $key, $blob); 21 | $count++; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /t/bogus-commands.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 1; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | print $sock "boguscommand slkdsldkfjsd\r\n"; 13 | is(scalar <$sock>, "ERROR\r\n", "got error back"); 14 | -------------------------------------------------------------------------------- /t/daemonize.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 7; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | use File::Temp qw(tempfile); 10 | 11 | my (undef, $tmpfn) = tempfile(); 12 | 13 | my $server = new_memcached("-d -P $tmpfn"); 14 | my $sock = $server->sock; 15 | sleep 0.5; 16 | 17 | ok(-e $tmpfn, "pid file exists"); 18 | ok(-s $tmpfn, "pid file has length"); 19 | 20 | open (my $fh, $tmpfn) or die; 21 | my $readpid = do { local $/; <$fh>; }; 22 | chomp $readpid; 23 | close ($fh); 24 | 25 | ok(kill(0, $readpid), "process is still running"); 26 | 27 | my $stats = mem_stats($sock); 28 | is($stats->{pid}, $readpid, "memcached reports same pid as file"); 29 | 30 | ok($server->new_sock, "opened new socket"); 31 | ok(kill(9, $readpid), "sent KILL signal"); 32 | sleep 0.5; 33 | ok(! $server->new_sock, "failed to open new socket"); 34 | -------------------------------------------------------------------------------- /t/dash-M.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached('-M -m 1'); 10 | my $sock = $server->sock; 11 | 12 | my $value = "B" x 8192; 13 | my $vallen = length($value); 14 | 15 | my $resp = "STORED\r\n"; 16 | my $key = 0; 17 | 18 | while($resp eq "STORED\r\n") { 19 | print $sock "set dash$key 0 0 $vallen\r\n$value\r\n"; 20 | $key++; 21 | $resp = scalar <$sock>; 22 | } 23 | 24 | my $max_stored = $key - 1; 25 | 26 | plan tests => $max_stored + 1; 27 | 28 | print $sock "set dash$key 0 0 $vallen\r\n$value\r\n"; 29 | is(scalar <$sock>, "SERVER_ERROR out of memory storing object\r\n", 30 | "failed to add another one."); 31 | 32 | for($key = 0; $key < $max_stored; $key++) { 33 | mem_get_is $sock, "dash$key", $value, "Failed at dash$key"; 34 | } 35 | -------------------------------------------------------------------------------- /t/expirations.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 15; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $expire; 12 | 13 | sub wait_for_early_second { 14 | my $have_hires = eval "use Time::HiRes (); 1"; 15 | if ($have_hires) { 16 | my $tsh = Time::HiRes::time(); 17 | my $ts = int($tsh); 18 | return if ($tsh - $ts) < 0.5; 19 | } 20 | 21 | my $ts = int(time()); 22 | while (1) { 23 | my $t = int(time()); 24 | return if $t != $ts; 25 | select undef, undef, undef, 0.10; # 1/10th of a second sleeps until time changes. 26 | } 27 | } 28 | 29 | wait_for_early_second(); 30 | 31 | print $sock "set foo 0 1 6\r\nfooval\r\n"; 32 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 33 | 34 | mem_get_is($sock, "foo", "fooval"); 35 | sleep(1.5); 36 | mem_get_is($sock, "foo", undef); 37 | 38 | $expire = time() - 1; 39 | print $sock "set foo 0 $expire 6\r\nfooval\r\n"; 40 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 41 | mem_get_is($sock, "foo", undef, "already expired"); 42 | 43 | $expire = time() + 1; 44 | print $sock "set foo 0 $expire 6\r\nfoov+1\r\n"; 45 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 46 | mem_get_is($sock, "foo", "foov+1"); 47 | sleep(2.2); 48 | mem_get_is($sock, "foo", undef, "now expired"); 49 | 50 | $expire = time() - 20; 51 | print $sock "set boo 0 $expire 6\r\nbooval\r\n"; 52 | is(scalar <$sock>, "STORED\r\n", "stored boo"); 53 | mem_get_is($sock, "boo", undef, "now expired"); 54 | 55 | print $sock "add add 0 2 6\r\naddval\r\n"; 56 | is(scalar <$sock>, "STORED\r\n", "stored add"); 57 | mem_get_is($sock, "add", "addval"); 58 | # second add fails 59 | print $sock "add add 0 2 7\r\naddval2\r\n"; 60 | is(scalar <$sock>, "NOT_STORED\r\n", "add failure"); 61 | sleep(2.3); 62 | print $sock "add add 0 2 7\r\naddval3\r\n"; 63 | is(scalar <$sock>, "STORED\r\n", "stored add again"); 64 | mem_get_is($sock, "add", "addval3"); 65 | -------------------------------------------------------------------------------- /t/flags.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 6; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | # set foo (and should get it) 13 | for my $flags (0, 123, 2**16-1) { 14 | print $sock "set foo $flags 0 6\r\nfooval\r\n"; 15 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 16 | mem_get_is({ sock => $sock, 17 | flags => $flags }, "foo", "fooval", "got flags $flags back"); 18 | } 19 | -------------------------------------------------------------------------------- /t/flush-all.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 14; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $expire; 12 | 13 | print $sock "set foo 0 0 6\r\nfooval\r\n"; 14 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 15 | 16 | mem_get_is($sock, "foo", "fooval"); 17 | print $sock "flush_all\r\n"; 18 | is(scalar <$sock>, "OK\r\n", "did flush_all"); 19 | mem_get_is($sock, "foo", undef); 20 | 21 | # Test flush_all with zero delay. 22 | print $sock "set foo 0 0 6\r\nfooval\r\n"; 23 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 24 | 25 | mem_get_is($sock, "foo", "fooval"); 26 | print $sock "flush_all 0\r\n"; 27 | is(scalar <$sock>, "OK\r\n", "did flush_all"); 28 | mem_get_is($sock, "foo", undef); 29 | 30 | # check that flush_all doesn't blow away items that immediately get set 31 | print $sock "set foo 0 0 3\r\nnew\r\n"; 32 | is(scalar <$sock>, "STORED\r\n", "stored foo = 'new'"); 33 | mem_get_is($sock, "foo", 'new'); 34 | 35 | # and the other form, specifying a flush_all time... 36 | my $expire = time() + 2; 37 | print $sock "flush_all $expire\r\n"; 38 | is(scalar <$sock>, "OK\r\n", "did flush_all in future"); 39 | 40 | print $sock "set foo 0 0 4\r\n1234\r\n"; 41 | is(scalar <$sock>, "STORED\r\n", "stored foo = '1234'"); 42 | mem_get_is($sock, "foo", '1234'); 43 | sleep(2.2); 44 | mem_get_is($sock, "foo", undef); 45 | -------------------------------------------------------------------------------- /t/getset.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 539; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | 10 | my $server = new_memcached(); 11 | my $sock = $server->sock; 12 | 13 | 14 | # set foo (and should get it) 15 | print $sock "set foo 0 0 6\r\nfooval\r\n"; 16 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 17 | mem_get_is($sock, "foo", "fooval"); 18 | 19 | # add bar (and should get it) 20 | print $sock "add bar 0 0 6\r\nbarval\r\n"; 21 | is(scalar <$sock>, "STORED\r\n", "stored barval"); 22 | mem_get_is($sock, "bar", "barval"); 23 | 24 | # add foo (but shouldn't get new value) 25 | print $sock "add foo 0 0 5\r\nfoov2\r\n"; 26 | is(scalar <$sock>, "NOT_STORED\r\n", "not stored"); 27 | mem_get_is($sock, "foo", "fooval"); 28 | 29 | # replace bar (should work) 30 | print $sock "replace bar 0 0 6\r\nbarva2\r\n"; 31 | is(scalar <$sock>, "STORED\r\n", "replaced barval 2"); 32 | 33 | # replace notexist (shouldn't work) 34 | print $sock "replace notexist 0 0 6\r\nbarva2\r\n"; 35 | is(scalar <$sock>, "NOT_STORED\r\n", "didn't replace notexist"); 36 | 37 | # delete foo. 38 | print $sock "delete foo\r\n"; 39 | is(scalar <$sock>, "DELETED\r\n", "deleted foo"); 40 | 41 | # delete foo again. not found this time. 42 | print $sock "delete foo\r\n"; 43 | is(scalar <$sock>, "NOT_FOUND\r\n", "deleted foo, but not found"); 44 | 45 | # add moo 46 | # 47 | print $sock "add moo 0 0 6\r\nmooval\r\n"; 48 | is(scalar <$sock>, "STORED\r\n", "stored barval"); 49 | mem_get_is($sock, "moo", "mooval"); 50 | 51 | # check-and-set (cas) failure case, try to set value with incorrect cas unique val 52 | print $sock "cas moo 0 0 6 0\r\nMOOVAL\r\n"; 53 | is(scalar <$sock>, "EXISTS\r\n", "check and set with invalid id"); 54 | 55 | # test "gets", grab unique ID 56 | print $sock "gets moo\r\n"; 57 | # VALUE moo 0 6 3084947704 58 | # 59 | my @retvals = split(/ /, scalar <$sock>); 60 | my $data = scalar <$sock>; # grab data 61 | my $dot = scalar <$sock>; # grab dot on line by itself 62 | is($retvals[0], "VALUE", "get value using 'gets'"); 63 | my $unique_id = $retvals[4]; 64 | # clean off \r\n 65 | $unique_id =~ s/\r\n$//; 66 | ok($unique_id =~ /^\d+$/, "unique ID '$unique_id' is an integer"); 67 | # now test that we can store moo with the correct unique id 68 | print $sock "cas moo 0 0 6 $unique_id\r\nMOOVAL\r\n"; 69 | is(scalar <$sock>, "STORED\r\n"); 70 | mem_get_is($sock, "moo", "MOOVAL"); 71 | 72 | # pipeling is okay 73 | print $sock "set foo 0 0 6\r\nfooval\r\ndelete foo\r\nset foo 0 0 6\r\nfooval\r\ndelete foo\r\n"; 74 | is(scalar <$sock>, "STORED\r\n", "pipeline set"); 75 | is(scalar <$sock>, "DELETED\r\n", "pipeline delete"); 76 | is(scalar <$sock>, "STORED\r\n", "pipeline set"); 77 | is(scalar <$sock>, "DELETED\r\n", "pipeline delete"); 78 | 79 | 80 | # Test sets up to a large size around 1MB. 81 | # Everything up to 1MB - 1k should succeed, everything 1MB +1k should fail. 82 | 83 | my $len = 1024; 84 | while ($len < 1024*1028) { 85 | my $val = "B"x$len; 86 | if ($len > (1024*1024)) { 87 | # Ensure causing a memory overflow doesn't leave stale data. 88 | print $sock "set foo_$len 0 0 3\r\nMOO\r\n"; 89 | is(scalar <$sock>, "STORED\r\n"); 90 | print $sock "set foo_$len 0 0 $len\r\n$val\r\n"; 91 | is(scalar <$sock>, "SERVER_ERROR object too large for cache\r\n", "failed to store size $len"); 92 | mem_get_is($sock, "foo_$len"); 93 | } else { 94 | print $sock "set foo_$len 0 0 $len\r\n$val\r\n"; 95 | is(scalar <$sock>, "STORED\r\n", "stored size $len"); 96 | } 97 | $len += 2048; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /t/incrdecr.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 23; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | # Bug 21 13 | print $sock "set bug21 0 0 19\r\n9223372036854775807\r\n"; 14 | is(scalar <$sock>, "STORED\r\n", "stored text"); 15 | print $sock "incr bug21 1\r\n"; 16 | is(scalar <$sock>, "9223372036854775808\r\n", "bug21 incr 1"); 17 | print $sock "incr bug21 1\r\n"; 18 | is(scalar <$sock>, "9223372036854775809\r\n", "bug21 incr 2"); 19 | print $sock "decr bug21 1\r\n"; 20 | is(scalar <$sock>, "9223372036854775808\r\n", "bug21 decr"); 21 | 22 | print $sock "set num 0 0 1\r\n1\r\n"; 23 | is(scalar <$sock>, "STORED\r\n", "stored num"); 24 | mem_get_is($sock, "num", 1, "stored 1"); 25 | 26 | print $sock "incr num 1\r\n"; 27 | is(scalar <$sock>, "2\r\n", "+ 1 = 2"); 28 | mem_get_is($sock, "num", 2); 29 | 30 | print $sock "incr num 8\r\n"; 31 | is(scalar <$sock>, "10\r\n", "+ 8 = 10"); 32 | mem_get_is($sock, "num", 10); 33 | 34 | print $sock "decr num 1\r\n"; 35 | is(scalar <$sock>, "9\r\n", "- 1 = 9"); 36 | 37 | print $sock "decr num 9\r\n"; 38 | is(scalar <$sock>, "0\r\n", "- 9 = 0"); 39 | 40 | print $sock "decr num 5\r\n"; 41 | is(scalar <$sock>, "0\r\n", "- 5 = 0"); 42 | 43 | printf $sock "set num 0 0 10\r\n4294967296\r\n"; 44 | is(scalar <$sock>, "STORED\r\n", "stored 2**32"); 45 | 46 | print $sock "incr num 1\r\n"; 47 | is(scalar <$sock>, "4294967297\r\n", "4294967296 + 1 = 4294967297"); 48 | 49 | printf $sock "set num 0 0 %d\r\n18446744073709551615\r\n", length("18446744073709551615"); 50 | is(scalar <$sock>, "STORED\r\n", "stored 2**64-1"); 51 | 52 | print $sock "incr num 1\r\n"; 53 | is(scalar <$sock>, "0\r\n", "(2**64 - 1) + 1 = 0"); 54 | 55 | print $sock "decr bogus 5\r\n"; 56 | is(scalar <$sock>, "NOT_FOUND\r\n", "can't decr bogus key"); 57 | 58 | print $sock "decr incr 5\r\n"; 59 | is(scalar <$sock>, "NOT_FOUND\r\n", "can't incr bogus key"); 60 | 61 | print $sock "set bigincr 0 0 1\r\n0\r\n"; 62 | is(scalar <$sock>, "STORED\r\n", "stored bigincr"); 63 | print $sock "incr bigincr 18446744073709551610\r\n"; 64 | is(scalar <$sock>, "18446744073709551610\r\n"); 65 | 66 | print $sock "set text 0 0 2\r\nhi\r\n"; 67 | is(scalar <$sock>, "STORED\r\n", "stored hi"); 68 | print $sock "incr text 1\r\n"; 69 | is(scalar <$sock>, 70 | "CLIENT_ERROR cannot increment or decrement non-numeric value\r\n", 71 | "hi - 1 = 0"); 72 | -------------------------------------------------------------------------------- /t/issue_14.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 21; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $value = "B"x66560; 12 | my $key = 0; 13 | 14 | for ($key = 0; $key < 10; $key++) { 15 | print $sock "set key$key 0 2 66560\r\n$value\r\n"; 16 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 17 | } 18 | 19 | #print $sock "stats slabs" 20 | my $first_stats = mem_stats($sock, "slabs"); 21 | my $first_malloc = $first_stats->{total_malloced}; 22 | 23 | sleep(4); 24 | 25 | for ($key = 10; $key < 20; $key++) { 26 | print $sock "set key$key 0 2 66560\r\n$value\r\n"; 27 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 28 | } 29 | 30 | my $second_stats = mem_stats($sock, "slabs"); 31 | my $second_malloc = $second_stats->{total_malloced}; 32 | 33 | 34 | is ($second_malloc, $first_malloc, "Memory grows..") 35 | -------------------------------------------------------------------------------- /t/issue_22.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 84; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached("-m 3"); 10 | my $sock = $server->sock; 11 | my $value = "B"x66560; 12 | my $key = 0; 13 | 14 | for ($key = 0; $key < 40; $key++) { 15 | print $sock "set key$key 0 0 66560\r\n$value\r\n"; 16 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 17 | } 18 | 19 | my $first_stats = mem_stats($sock, "items"); 20 | my $first_evicted = $first_stats->{"items:31:evicted"}; 21 | # I get 1 eviction on a 32 bit binary, but 4 on a 64 binary.. 22 | # Just check that I have evictions... 23 | isnt ($first_evicted, "0", "check evicted"); 24 | 25 | print $sock "stats reset\r\n"; 26 | is (scalar <$sock>, "RESET\r\n", "Stats reset"); 27 | 28 | my $second_stats = mem_stats($sock, "items"); 29 | my $second_evicted = $second_stats->{"items:31:evicted"}; 30 | is ("0", $second_evicted, "check evicted"); 31 | 32 | for ($key = 40; $key < 80; $key++) { 33 | print $sock "set key$key 0 0 66560\r\n$value\r\n"; 34 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 35 | } 36 | 37 | my $last_stats = mem_stats($sock, "items"); 38 | my $last_evicted = $last_stats->{"items:31:evicted"}; 39 | is ($last_evicted, "40", "check evicted"); 40 | -------------------------------------------------------------------------------- /t/issue_29.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 4; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | print $sock "set issue29 0 0 0\r\n\r\n"; 13 | is (scalar <$sock>, "STORED\r\n", "stored issue29"); 14 | 15 | my $first_stats = mem_stats($sock, "slabs"); 16 | my $first_used = $first_stats->{"1:used_chunks"}; 17 | 18 | is(1, $first_used, "Used one"); 19 | 20 | print $sock "set issue29_b 0 0 0\r\n\r\n"; 21 | is (scalar <$sock>, "STORED\r\n", "stored issue29_b"); 22 | 23 | my $second_stats = mem_stats($sock, "slabs"); 24 | my $second_used = $second_stats->{"1:used_chunks"}; 25 | 26 | is(2, $second_used, "Used two") 27 | -------------------------------------------------------------------------------- /t/issue_41.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use POSIX qw(ceil); 6 | use Test::More tests => 691; 7 | use FindBin qw($Bin); 8 | use lib "$Bin/lib"; 9 | use MemcachedTest; 10 | 11 | my $server = new_memcached(); 12 | my $sock = $server->sock; 13 | 14 | my $factor = 2; 15 | my $val = "x" x $factor; 16 | my $key = ''; 17 | 18 | # SET items of diverse size to the daemon so it can attempt 19 | # to return a large stats output for slabs 20 | for (my $i=0; $i<69; $i++) { 21 | for (my $j=0; $j<10; $j++) { 22 | $key = "$i:$j"; 23 | print $sock "set key$key 0 0 $factor\r\n$val\r\n"; 24 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 25 | } 26 | $factor *= 1.2; 27 | $factor = ceil($factor); 28 | $val = "x" x $factor; 29 | } 30 | 31 | # This request will kill the daemon if it has not allocated 32 | # enough memory internally. 33 | my $stats = mem_stats($sock, "slabs"); 34 | 35 | # Verify whether the daemon is still running or not by asking 36 | # it for statistics. 37 | print $sock "version\r\n"; 38 | my $v = scalar <$sock>; 39 | ok(defined $v && length($v), "memcached didn't respond"); 40 | -------------------------------------------------------------------------------- /t/issue_42.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 11; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $value = "B"x10; 12 | my $key = 0; 13 | 14 | for ($key = 0; $key < 10; $key++) { 15 | print $sock "set key$key 0 0 10\r\n$value\r\n"; 16 | is (scalar <$sock>, "STORED\r\n", "stored key$key"); 17 | } 18 | 19 | my $first_stats = mem_stats($sock, "slabs"); 20 | my $req = $first_stats->{"1:mem_requested"}; 21 | ok ($req == "640" || $req == "800", "Check allocated size"); 22 | -------------------------------------------------------------------------------- /t/issue_50.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 1; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached('-B binary'); 10 | my $sock = $server->sock; 11 | 12 | $SIG{ALRM} = sub { die "alarm\n" }; 13 | alarm(2); 14 | print $sock "Here's a bunch of garbage that doesn't look like the bin prot."; 15 | my $rv = <$sock>; 16 | ok(1, "Either the above worked and quit, or hung forever."); 17 | -------------------------------------------------------------------------------- /t/issue_61.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 7; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached("-R 1"); 10 | my $sock = $server->sock; 11 | 12 | print $sock "set foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\n"; 13 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 14 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 15 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 16 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 17 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 18 | is (scalar <$sock>, "STORED\r\n", "stored foobar"); 19 | my $stats = mem_stats($sock); 20 | is ($stats->{"conn_yields"}, "5", "Got a decent number of yields"); 21 | -------------------------------------------------------------------------------- /t/issue_70.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 4; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | print $sock "set issue70 0 0 0\r\n\r\n"; 13 | is (scalar <$sock>, "STORED\r\n", "stored issue70"); 14 | 15 | print $sock "set issue70 0 0 -1\r\n"; 16 | is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); 17 | 18 | print $sock "set issue70 0 0 4294967295\r\n"; 19 | is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); 20 | 21 | print $sock "set issue70 0 0 2147483647\r\nscoobyscoobydoo"; 22 | is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); 23 | -------------------------------------------------------------------------------- /t/line-lengths.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use FindBin qw($Bin); 4 | our @files; 5 | 6 | BEGIN { 7 | chdir "$Bin/.." or die; 8 | @files = ( "doc/protocol.txt" ); 9 | } 10 | 11 | use Test::More tests => scalar(@files); 12 | 13 | foreach my $f (@files) { 14 | open(my $fh, $f) or die("Can't open $f"); 15 | my @long_lines = (); 16 | my $line_number = 0; 17 | while(<$fh>) { 18 | $line_number++; 19 | if(length($_) > 80) { 20 | push(@long_lines, $line_number); 21 | } 22 | } 23 | close($fh); 24 | ok(@long_lines == 0, "$f has a long lines: @long_lines"); 25 | } 26 | -------------------------------------------------------------------------------- /t/lru.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 149; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | # assuming max slab is 1M and default mem is 64M 10 | my $server = new_memcached(); 11 | my $sock = $server->sock; 12 | 13 | # create a big value for the largest slab 14 | my $max = 1024 * 1024; 15 | my $big = "a big value that's > .5M and < 1M. "; 16 | while (length($big) * 2 < $max) { 17 | $big = $big . $big; 18 | } 19 | 20 | ok(length($big) > 512 * 1024); 21 | ok(length($big) < 1024 * 1024); 22 | 23 | # test that an even bigger value is rejected while we're here 24 | my $too_big = $big . $big . $big; 25 | my $len = length($too_big); 26 | print $sock "set too_big 0 0 $len\r\n$too_big\r\n"; 27 | is(scalar <$sock>, "SERVER_ERROR object too large for cache\r\n", "too_big not stored"); 28 | 29 | # set the big value 30 | my $len = length($big); 31 | print $sock "set big 0 0 $len\r\n$big\r\n"; 32 | is(scalar <$sock>, "STORED\r\n", "stored big"); 33 | mem_get_is($sock, "big", $big); 34 | 35 | # no evictions yet 36 | my $stats = mem_stats($sock); 37 | is($stats->{"evictions"}, "0", "no evictions to start"); 38 | 39 | # set many big items, enough to get evictions 40 | for (my $i = 0; $i < 100; $i++) { 41 | print $sock "set item_$i 0 0 $len\r\n$big\r\n"; 42 | is(scalar <$sock>, "STORED\r\n", "stored item_$i"); 43 | } 44 | 45 | # some evictions should have happened 46 | my $stats = mem_stats($sock); 47 | my $evictions = int($stats->{"evictions"}); 48 | ok($evictions == 37, "some evictions happened"); 49 | 50 | # the first big value should be gone 51 | mem_get_is($sock, "big", undef); 52 | 53 | # the earliest items should be gone too 54 | for (my $i = 0; $i < $evictions - 1; $i++) { 55 | mem_get_is($sock, "item_$i", undef); 56 | } 57 | 58 | # check that the non-evicted are the right ones 59 | for (my $i = $evictions - 1; $i < $evictions + 4; $i++) { 60 | mem_get_is($sock, "item_$i", $big); 61 | } 62 | -------------------------------------------------------------------------------- /t/maxconns.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Test::More tests => 11; 7 | 8 | use FindBin qw($Bin); 9 | use lib "$Bin/lib"; 10 | use MemcachedTest; 11 | 12 | 13 | # start up a server with 10 maximum connections 14 | my $server = new_memcached('-c 10'); 15 | my $sock = $server->sock; 16 | my @sockets; 17 | 18 | ok(defined($sock), 'Connection 0'); 19 | push (@sockets, $sock); 20 | 21 | 22 | foreach my $conn (1..10) { 23 | $sock = $server->new_sock; 24 | ok(defined($sock), "Made connection $conn"); 25 | push(@sockets, $sock); 26 | } 27 | -------------------------------------------------------------------------------- /t/memcacheConstants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | Copyright (c) 2007 Dustin Sallings 5 | """ 6 | 7 | import struct 8 | 9 | # Command constants 10 | CMD_GET = 0 11 | CMD_SET = 1 12 | CMD_ADD = 2 13 | CMD_REPLACE = 3 14 | CMD_DELETE = 4 15 | CMD_INCR = 5 16 | CMD_DECR = 6 17 | CMD_QUIT = 7 18 | CMD_FLUSH = 8 19 | CMD_GETQ = 9 20 | CMD_NOOP = 0x0a 21 | CMD_VERSION = 0x0b 22 | CMD_GETK = 0x0c 23 | CMD_GETKQ = 0x0d 24 | CMD_APPEND = 0x0e 25 | CMD_PREPEND = 0x0f 26 | CMD_STAT = 0x10 27 | 28 | # SASL stuff 29 | CMD_SASL_LIST_MECHS = 0x20 30 | CMD_SASL_AUTH = 0x21 31 | CMD_SASL_STEP = 0x22 32 | 33 | # Bucket extension 34 | CMD_CREATE_BUCKET = 0x25 35 | CMD_DELETE_BUCKET = 0x26 36 | CMD_LIST_BUCKETS = 0x27 37 | CMD_EXPAND_BUCKET = 0x28 38 | 39 | CMD_STOP_PERSISTENCE = 0x80 40 | CMD_START_PERSISTENCE = 0x81 41 | CMD_SET_FLUSH_PARAM = 0x82 42 | 43 | CMD_START_REPLICATION = 0x90 44 | CMD_STOP_REPLICATION = 0x91 45 | CMD_SET_TAP_PARAM = 0x92 46 | CMD_EVICT_KEY = 0x93 47 | 48 | # Replication 49 | CMD_TAP_CONNECT = 0x40 50 | CMD_TAP_MUTATION = 0x41 51 | CMD_TAP_DELETE = 0x42 52 | CMD_TAP_FLUSH = 0x43 53 | CMD_TAP_OPAQUE = 0x44 54 | 55 | # vbucket stuff 56 | CMD_SET_VBUCKET_STATE = 0x83 57 | CMD_GET_VBUCKET_STATE = 0x84 58 | CMD_DELETE_VBUCKET = 0x85 59 | 60 | COMMAND_NAMES = dict(((globals()[k], k) for k in globals() if k.startswith("CMD_"))) 61 | 62 | # TAP flags 63 | TAP_FLAG_BACKFILL = 0x01 64 | TAP_FLAG_DUMP = 0x02 65 | 66 | TAP_FLAG_TYPES = {TAP_FLAG_BACKFILL: ">Q", 67 | TAP_FLAG_DUMP: ""} 68 | 69 | # Flags, expiration 70 | SET_PKT_FMT=">II" 71 | 72 | # flags 73 | GET_RES_FMT=">I" 74 | 75 | # How long until the deletion takes effect. 76 | DEL_PKT_FMT="" 77 | 78 | ## TAP stuff 79 | # eng-specific length, flags, ttl, [res, res, res]; item flags, exp 80 | TAP_MUTATION_PKT_FMT = "HHbxxxII" 81 | TAP_GENERAL_PKT_FMT = "HHbxxx" 82 | 83 | # amount, initial value, expiration 84 | INCRDECR_PKT_FMT=">QQI" 85 | # Special incr expiration that means do not store 86 | INCRDECR_SPECIAL=0xffffffff 87 | INCRDECR_RES_FMT=">Q" 88 | 89 | # Time bomb 90 | FLUSH_PKT_FMT=">I" 91 | 92 | MAGIC_BYTE = 0x80 93 | REQ_MAGIC_BYTE = 0x80 94 | RES_MAGIC_BYTE = 0x81 95 | 96 | # magic, opcode, keylen, extralen, datatype, vbucket, bodylen, opaque, cas 97 | REQ_PKT_FMT=">BBHBBHIIQ" 98 | # magic, opcode, keylen, extralen, datatype, status, bodylen, opaque, cas 99 | RES_PKT_FMT=">BBHBBHIIQ" 100 | # min recv packet size 101 | MIN_RECV_PACKET = struct.calcsize(REQ_PKT_FMT) 102 | # The header sizes don't deviate 103 | assert struct.calcsize(REQ_PKT_FMT) == struct.calcsize(RES_PKT_FMT) 104 | 105 | EXTRA_HDR_FMTS={ 106 | CMD_SET: SET_PKT_FMT, 107 | CMD_ADD: SET_PKT_FMT, 108 | CMD_REPLACE: SET_PKT_FMT, 109 | CMD_INCR: INCRDECR_PKT_FMT, 110 | CMD_DECR: INCRDECR_PKT_FMT, 111 | CMD_DELETE: DEL_PKT_FMT, 112 | CMD_FLUSH: FLUSH_PKT_FMT, 113 | CMD_TAP_MUTATION: TAP_MUTATION_PKT_FMT, 114 | CMD_TAP_DELETE: TAP_GENERAL_PKT_FMT, 115 | CMD_TAP_FLUSH: TAP_GENERAL_PKT_FMT, 116 | CMD_TAP_OPAQUE: TAP_GENERAL_PKT_FMT, 117 | } 118 | 119 | EXTRA_HDR_SIZES=dict( 120 | [(k, struct.calcsize(v)) for (k,v) in EXTRA_HDR_FMTS.items()]) 121 | 122 | ERR_UNKNOWN_CMD = 0x81 123 | ERR_NOT_FOUND = 0x1 124 | ERR_EXISTS = 0x2 125 | ERR_AUTH = 0x20 126 | ERR_AUTH_CONTINUE = 0x21 127 | 128 | ERR_SUCCESS = 0x00 129 | ERR_KEY_ENOENT = 0x01 130 | ERR_KEY_EEXISTS = 0x02 131 | ERR_E2BIG = 0x03 132 | ERR_EINVAL = 0x04 133 | ERR_NOT_STORED = 0x05 134 | ERR_DELTA_BADVAL = 0x06 135 | ERR_NOT_MY_VBUCKET = 0x07 136 | ERR_AUTH_ERROR = 0x20 137 | ERR_AUTH_CONTINUE = 0x21 138 | ERR_UNKNOWN_COMMAND = 0x81 139 | ERR_ENOMEM = 0x82 140 | ERR_NOT_SUPPORTED = 0x83 141 | ERR_EINTERNAL = 0x84 142 | ERR_EBUSY = 0x85 143 | -------------------------------------------------------------------------------- /t/moxi.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | 5 | # Invoke like this to test ascii protocol, with all the topologies. 6 | # 7 | # ./t/moxi.pl simple ascii && ./t/moxi.pl chain ascii && 8 | # ./t/moxi.pl fanout ascii && ./t/moxi.pl fanoutin ascii 9 | # 10 | # Invoke like this to test binary protocol. 11 | # 12 | # ./t/moxi.pl simple binary && ./t/moxi.pl fanout binary 13 | # 14 | # See: ./t/moxi_all.pl 15 | # 16 | # TODO: We can't pass chain and fanoutin topologies with binary protocol 17 | # until moxi supports upstream binary protocol. 18 | # 19 | my $topology_name = $ARGV[0] || 'simple'; 20 | my $protocol_name = $ARGV[1] || 'ascii'; 21 | my $hashlib_name = $ARGV[2] || 'libvbucket'; 22 | 23 | print "moxi.pl: " . $topology_name . " " . $protocol_name . " " . $hashlib_name . "\n"; 24 | 25 | my @good_tests = qw( 26 | binary-get.t 27 | bogus-commands.t 28 | cas.t 29 | expirations.t 30 | flags.t 31 | incrdecr.t 32 | line-lengths.t 33 | maxconns.t 34 | multiversioning.t 35 | slab-reassign.t 36 | whitespace.t 37 | ); 38 | 39 | my @skip_tests = qw( 40 | # TODO: SKIP: The noreply test fails because moxi uses 41 | # a pool of multiple concurrent downstream 42 | # connections rather than respecting the 43 | # serial expectations of the noreply test. 44 | # 45 | noreply.t 46 | 47 | # TODO: SKIP: The getset test fails because the failed set 48 | # of a huge >1MB value or failed item_alloc() does 49 | # not currently delete the item from the downstream 50 | # memcached server. 51 | # 52 | getset.t 53 | 54 | # TODO: Currently don't know why flush-all tests are failing against 55 | # the latest moxi. 56 | # 57 | flush-all.t 58 | 59 | # The following tests are not expected to succeed, 60 | # because they're testing command line stuff, 61 | # or the stats are wrong. 62 | # 63 | 00-startup.t 64 | 64bit.t 65 | binary.t 66 | daemonize.t 67 | dash-M.t 68 | issue_14.t 69 | issue_22.t 70 | issue_29.t 71 | lru.t 72 | stats-detail.t 73 | stats.t 74 | udp.t 75 | unixsocket.t 76 | ); 77 | 78 | my %is_good_test; 79 | my %is_skip_test; 80 | 81 | for (map("./t/$_", @good_tests)) { 82 | $is_good_test{$_} = "ascii binary simple chain fanout fanoutin" 83 | } 84 | for (map("./t/$_", @skip_tests)) { 85 | $is_skip_test{$_} = "ascii binary simple chain fanout fanoutin" 86 | } 87 | 88 | # Skipping incrdecr.t for binary due to issue 48 89 | # on code.google.com/p/memcached. 90 | # 91 | $is_good_test{"./t/incrdecr.t"} = "ascii simple chain fanout fanoutin"; 92 | $is_skip_test{"./t/incrdecr.t"} = "binary simple chain fanout fanoutin"; 93 | 94 | # Skipping cas.t for fanout/fanoutin due to multi-"gets" race condition. 95 | # The test expects "gets x y" to return results in order "x y", but 96 | # when moxi does a fanout, the order is non-deterministic. 97 | # 98 | $is_good_test{"./t/cas.t"} = "ascii binary simple chain"; 99 | $is_skip_test{"./t/cas.t"} = "ascii binary fanout fanoutin"; 100 | 101 | my $file; 102 | 103 | foreach $file (<./t/*.t>) { 104 | if ($is_good_test{$file} =~ /$protocol_name/ && 105 | $is_good_test{$file} =~ /$topology_name/) { 106 | print $file . "\n"; 107 | my $result = system("./t/moxi_one.pl $file $topology_name $protocol_name $hashlib_name"); 108 | if ($result != 0) { 109 | print "fail moxi_one.pl $file $topology_name $protocol_name $hashlib_name test"; 110 | exit $result; 111 | } 112 | } elsif ($is_skip_test{$file} =~ /$protocol_name/ && 113 | $is_skip_test{$file} =~ /$topology_name/) { 114 | print "skipping test: $file\n"; 115 | } else { 116 | print "unknown test: $file\n"; 117 | } 118 | } 119 | 120 | 121 | -------------------------------------------------------------------------------- /t/moxi_all.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Run this main test driver program from the project's 4 | # top directory, which has t as a subdirectory. 5 | # 6 | my $exe = "./moxi"; 7 | 8 | use Carp qw(croak); 9 | 10 | croak("moxi binary doesn't exist. Haven't run 'make' ?\n") unless -e $exe; 11 | croak("moxi binary not executable\n") unless -x _; 12 | 13 | sub go { 14 | my ($topology, $protocol) = @_; 15 | print "------------------------------------\n"; 16 | print "testing $topology $protocol\n"; 17 | my $result = system("./t/moxi.pl $topology $protocol"); 18 | if ($result != 0) { 19 | print("fail moxi.pl $topology $protocol test\n"); 20 | exit $result; 21 | } 22 | } 23 | 24 | # Ascii protocol compatibility tests. 25 | # 26 | go('simple', 'ascii'); 27 | go('chain', 'ascii'); 28 | go('fanout', 'ascii'); 29 | go('fanoutin', 'ascii'); 30 | 31 | # Binary protocol compatibility tests. 32 | # 33 | go('simple', 'binary'); 34 | go('fanout', 'binary'); 35 | 36 | print "------------------------------------\n"; 37 | 38 | my $res = system("./t/moxi_mock.pl ascii"); 39 | 40 | exit $res; 41 | 42 | 43 | -------------------------------------------------------------------------------- /t/moxi_mock.cfg: -------------------------------------------------------------------------------- 1 | 11333 = { 2 | "hashAlgorithm": "CRC", 3 | "numReplicas": 0, 4 | "serverList": ["127.0.0.1:11311"], 5 | "vBucketMap": 6 | [ 7 | [0] 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /t/moxi_mock.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # This program starts moxi and then runs the python mock server tests. 4 | # 5 | # ./t/moxi_mock.pl [upstream_protocol] [downstream_protocol] [test_name] 6 | # 7 | # Parameters are optional, so these examples work, and default to ascii... 8 | # 9 | # ./t/moxi_mock.pl 10 | # ./t/moxi_mock.pl ascii 11 | # ./t/moxi_mock.pl ascii ascii TestProxyAscii.testBasicQuit 12 | # 13 | my $upstream_protocol = $ARGV[0] || 'ascii'; 14 | my $downstream_protocol = $ARGV[1] || 'ascii'; 15 | my $test_name = $ARGV[2] || ''; 16 | 17 | print "moxi_mock.pl: " . $upstream_protocol . " " . $downstream_protocol . " " . $test_name + "\n"; 18 | 19 | my $exe = "./moxi"; 20 | 21 | croak("moxi binary doesn't exist. Haven't run 'make' ?\n") unless -e $exe; 22 | croak("moxi binary not executable\n") unless -x _; 23 | 24 | # Fork moxi for moxi-specific testing. 25 | # 26 | my $childargs = 27 | " -z ./t/moxi_mock.cfg". 28 | " -p 0 -U 0 -v -t 1 -Z \"downstream_max=1,downstream_protocol=" . $downstream_protocol . "\""; 29 | if ($< == 0) { 30 | $childargs .= " -u root"; 31 | } 32 | my $childpid = fork(); 33 | 34 | unless ($childpid) { 35 | setpgrp(); 36 | exec "$exe $childargs"; 37 | exit; # never gets here. 38 | } 39 | setpgrp($childpid, $childpid); 40 | 41 | my $u = substr($upstream_protocol, 0, 1); # This is 'a' or 'b'. 42 | my $d = substr($downstream_protocol, 0, 1); # This is 'a' or 'b'. 43 | 44 | my $result = system("python ./t/moxi_mock_" . $u . "2" . $d . ".py " . $test_name); 45 | 46 | kill 2, -$childpid; 47 | 48 | exit $result; 49 | -------------------------------------------------------------------------------- /t/moxi_multitenancy_rest.cfg: -------------------------------------------------------------------------------- 1 | { "buckets": [ 2 | { "name": "bucket0", 3 | "vBucketServerMap": { 4 | "hashAlgorithm": "CRC", 5 | "numReplicas": 0, 6 | "user": "userGood0", 7 | "password": "passwordGood0", 8 | "serverList": ["127.0.0.1:11311"], 9 | "vBucketMap": 10 | [ [0] ] 11 | } 12 | }, 13 | { "name": "bucket1", 14 | "vBucketServerMap": { 15 | "hashAlgorithm": "CRC", 16 | "numReplicas": 0, 17 | "user": "userGood1", 18 | "password": "passwordGood1", 19 | "serverList": ["127.0.0.1:11311"], 20 | "vBucketMap": 21 | [ [0] ] 22 | } 23 | } 24 | ]} 25 | -------------------------------------------------------------------------------- /t/moxi_multitenancy_rest_default.cfg: -------------------------------------------------------------------------------- 1 | { "buckets": [ 2 | { "name": "default", 3 | "vBucketServerMap": { 4 | "hashAlgorithm": "CRC", 5 | "numReplicas": 0, 6 | "serverList": ["127.0.0.1:11311"], 7 | "vBucketMap": 8 | [ [0] ] 9 | } 10 | }, 11 | { "name": "bucket0", 12 | "vBucketServerMap": { 13 | "hashAlgorithm": "CRC", 14 | "numReplicas": 0, 15 | "user": "userGood0", 16 | "password": "passwordGood0", 17 | "serverList": ["127.0.0.1:11311"], 18 | "vBucketMap": 19 | [ [0] ] 20 | } 21 | }, 22 | { "name": "bucket1", 23 | "vBucketServerMap": { 24 | "hashAlgorithm": "CRC", 25 | "numReplicas": 0, 26 | "user": "userGood1", 27 | "password": "passwordGood1", 28 | "serverList": ["127.0.0.1:11311"], 29 | "vBucketMap": 30 | [ [0] ] 31 | } 32 | } 33 | ]} 34 | -------------------------------------------------------------------------------- /t/multiversioning.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 13; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $sock2 = $server->new_sock; 12 | 13 | ok($sock != $sock2, "have two different connections open"); 14 | 15 | # set large value 16 | my $size = 256 * 1024; # 256 kB 17 | my $bigval = "0123456789abcdef" x ($size / 16); 18 | $bigval =~ s/^0/\[/; $bigval =~ s/f$/\]/; 19 | my $bigval2 = uc($bigval); 20 | 21 | print $sock "set big 0 0 $size\r\n$bigval\r\n"; 22 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 23 | mem_get_is($sock, "big", $bigval, "big value got correctly"); 24 | 25 | print $sock "get big\r\n"; 26 | my $buf; 27 | is(read($sock, $buf, $size / 2), $size / 2, "read half the answer back"); 28 | like($buf, qr/VALUE big/, "buf has big value header in it"); 29 | like($buf, qr/abcdef/, "buf has some data in it"); 30 | unlike($buf, qr/abcde\]/, "buf doesn't yet close"); 31 | 32 | # sock2 interrupts (maybe sock1 is slow) and deletes stuff: 33 | print $sock2 "delete big\r\n"; 34 | is(scalar <$sock2>, "DELETED\r\n", "deleted big from sock2 while sock1's still reading it"); 35 | mem_get_is($sock2, "big", undef, "nothing from sock2 now. gone from namespace."); 36 | print $sock2 "set big 0 0 $size\r\n$bigval2\r\n"; 37 | is(scalar <$sock2>, "STORED\r\n", "stored big w/ val2"); 38 | mem_get_is($sock2, "big", $bigval2, "big value2 got correctly"); 39 | 40 | # sock1 resumes reading... 41 | $buf .= <$sock>; 42 | $buf .= <$sock>; 43 | like($buf, qr/abcde\]/, "buf now closes"); 44 | 45 | # and if sock1 reads again, it's the uppercase version: 46 | mem_get_is($sock, "big", $bigval2, "big value2 got correctly from sock1"); 47 | -------------------------------------------------------------------------------- /t/noreply.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 9; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | 10 | my $server = new_memcached(); 11 | my $sock = $server->sock; 12 | 13 | 14 | # Test that commands can take 'noreply' parameter. 15 | print $sock "flush_all noreply\r\n"; 16 | print $sock "flush_all 0 noreply\r\n"; 17 | 18 | print $sock "verbosity 0 noreply\r\n"; 19 | 20 | print $sock "add noreply:foo 0 0 1 noreply\r\n1\r\n"; 21 | mem_get_is($sock, "noreply:foo", "1"); 22 | 23 | print $sock "set noreply:foo 0 0 1 noreply\r\n2\r\n"; 24 | mem_get_is($sock, "noreply:foo", "2"); 25 | 26 | print $sock "replace noreply:foo 0 0 1 noreply\r\n3\r\n"; 27 | mem_get_is($sock, "noreply:foo", "3"); 28 | 29 | print $sock "append noreply:foo 0 0 1 noreply\r\n4\r\n"; 30 | mem_get_is($sock, "noreply:foo", "34"); 31 | 32 | print $sock "prepend noreply:foo 0 0 1 noreply\r\n5\r\n"; 33 | my @result = mem_gets($sock, "noreply:foo"); 34 | ok($result[1] eq "534"); 35 | 36 | print $sock "cas noreply:foo 0 0 1 $result[0] noreply\r\n6\r\n"; 37 | mem_get_is($sock, "noreply:foo", "6"); 38 | 39 | print $sock "incr noreply:foo 3 noreply\r\n"; 40 | mem_get_is($sock, "noreply:foo", "9"); 41 | 42 | print $sock "decr noreply:foo 2 noreply\r\n"; 43 | mem_get_is($sock, "noreply:foo", "7"); 44 | 45 | print $sock "delete noreply:foo noreply\r\n"; 46 | mem_get_is($sock, "noreply:foo"); 47 | 48 | -------------------------------------------------------------------------------- /t/rest_mock.rb: -------------------------------------------------------------------------------- 1 | # This is a fake http/REST server. 2 | # 3 | # ruby ./t/cluster_manager_mock.rb [optional_path_to_some_json_contents] 4 | # 5 | # For example... 6 | # 7 | # ruby ./t/cluster_manager_mock.rb ./t/vbucket1.cfg 8 | # 9 | require 'rubygems' 10 | require 'sinatra' 11 | 12 | get '/pools/default/buckets/default' do 13 | some_json 14 | end 15 | 16 | get '/pools/default/bucketsStreaming/default' do 17 | some_json + "\n\n\n\n" 18 | end 19 | 20 | get '/pools/default/bucketsStreamingConfig/default' do 21 | some_json + "\n\n\n\n" 22 | end 23 | 24 | def some_json() 25 | if ARGV.length > 0 26 | return File.read(ARGV[0]) 27 | end 28 | 29 | <<-eos 30 | { 31 | "hashAlgorithm": "CRC", 32 | "numReplicas": 0, 33 | "serverList": ["127.0.0.1:11311"], 34 | "vBucketMap": 35 | [ 36 | [0] 37 | ] 38 | } 39 | eos 40 | end 41 | 42 | -------------------------------------------------------------------------------- /t/slab-reassign.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More skip_all => "Tests not written."; # tests => 1 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | 12 | -------------------------------------------------------------------------------- /t/stats-detail.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 24; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $server = new_memcached(); 10 | my $sock = $server->sock; 11 | my $expire; 12 | 13 | print $sock "stats detail dump\r\n"; 14 | is(scalar <$sock>, "END\r\n", "verified empty stats at start"); 15 | 16 | print $sock "stats detail on\r\n"; 17 | is(scalar <$sock>, "OK\r\n", "detail collection turned on"); 18 | 19 | print $sock "set foo:123 0 0 6\r\nfooval\r\n"; 20 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 21 | 22 | print $sock "stats detail dump\r\n"; 23 | is(scalar <$sock>, "PREFIX foo get 0 hit 0 set 1 del 0\r\n", "details after set"); 24 | is(scalar <$sock>, "END\r\n", "end of details"); 25 | 26 | mem_get_is($sock, "foo:123", "fooval"); 27 | print $sock "stats detail dump\r\n"; 28 | is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 1 del 0\r\n", "details after get with hit"); 29 | is(scalar <$sock>, "END\r\n", "end of details"); 30 | 31 | mem_get_is($sock, "foo:124", undef); 32 | 33 | print $sock "stats detail dump\r\n"; 34 | is(scalar <$sock>, "PREFIX foo get 2 hit 1 set 1 del 0\r\n", "details after get without hit"); 35 | is(scalar <$sock>, "END\r\n", "end of details"); 36 | 37 | print $sock "delete foo:125 0\r\n"; 38 | is(scalar <$sock>, "NOT_FOUND\r\n", "sent delete command"); 39 | 40 | print $sock "stats detail dump\r\n"; 41 | is(scalar <$sock>, "PREFIX foo get 2 hit 1 set 1 del 1\r\n", "details after delete"); 42 | is(scalar <$sock>, "END\r\n", "end of details"); 43 | 44 | print $sock "stats reset\r\n"; 45 | is(scalar <$sock>, "RESET\r\n", "stats cleared"); 46 | 47 | print $sock "stats detail dump\r\n"; 48 | is(scalar <$sock>, "END\r\n", "empty stats after clear"); 49 | 50 | mem_get_is($sock, "foo:123", "fooval"); 51 | print $sock "stats detail dump\r\n"; 52 | is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 0 del 0\r\n", "details after clear and get"); 53 | is(scalar <$sock>, "END\r\n", "end of details"); 54 | 55 | print $sock "stats detail off\r\n"; 56 | is(scalar <$sock>, "OK\r\n", "detail collection turned off"); 57 | 58 | mem_get_is($sock, "foo:124", undef); 59 | 60 | mem_get_is($sock, "foo:123", "fooval"); 61 | print $sock "stats detail dump\r\n"; 62 | is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 0 del 0\r\n", "details after stats turned off"); 63 | is(scalar <$sock>, "END\r\n", "end of details"); 64 | -------------------------------------------------------------------------------- /t/stress-memcached.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | 4 | use strict; 5 | use lib '../../api/perl/lib'; 6 | use Cache::Memcached; 7 | use Time::HiRes qw(time); 8 | 9 | unless (@ARGV == 2) { 10 | die "Usage: stress-memcached.pl ip:port threads\n"; 11 | } 12 | 13 | my $host = shift; 14 | my $threads = shift; 15 | 16 | my $memc = new Cache::Memcached; 17 | $memc->set_servers([$host]); 18 | 19 | unless ($memc->set("foo", "bar") && 20 | $memc->get("foo") eq "bar") { 21 | die "memcached not running at $host ?\n"; 22 | } 23 | $memc->disconnect_all(); 24 | 25 | 26 | my $running = 0; 27 | while (1) { 28 | if ($running < $threads) { 29 | my $cpid = fork(); 30 | if ($cpid) { 31 | $running++; 32 | #print "Launched $cpid. Running $running threads.\n"; 33 | } else { 34 | stress(); 35 | exit 0; 36 | } 37 | } else { 38 | wait(); 39 | $running--; 40 | } 41 | } 42 | 43 | sub stress { 44 | undef $memc; 45 | $memc = new Cache::Memcached; 46 | $memc->set_servers([$host]); 47 | 48 | my ($t1, $t2); 49 | my $start = sub { $t1 = time(); }; 50 | my $stop = sub { 51 | my $op = shift; 52 | $t2 = time(); 53 | my $td = sprintf("%0.3f", $t2 - $t1); 54 | if ($td > 0.25) { print "Took $td seconds for: $op\n"; } 55 | }; 56 | 57 | my $max = rand(50); 58 | my $sets = 0; 59 | 60 | for (my $i = 0; $i < $max; $i++) { 61 | my $key = key($i); 62 | my $set = $memc->set($key, $key); 63 | $sets++ if $set; 64 | } 65 | 66 | for (1..int(rand(500))) { 67 | my $rand = int(rand($max)); 68 | my $key = key($rand); 69 | my $meth = int(rand(3)); 70 | my $exp = int(rand(3)); 71 | undef $exp unless $exp; 72 | $start->(); 73 | if ($meth == 0) { 74 | $memc->add($key, $key, $exp); 75 | $stop->("add"); 76 | } elsif ($meth == 1) { 77 | $memc->delete($key); 78 | $stop->("delete"); 79 | } else { 80 | $memc->set($key, $key, $exp); 81 | $stop->("set"); 82 | } 83 | $rand = int(rand($max)); 84 | $key = key($rand); 85 | $start->(); 86 | my $v = $memc->get($key); 87 | $stop->("get"); 88 | if ($v && $v ne $key) { die "Bogus: $v for key $rand\n"; } 89 | } 90 | 91 | $start->(); 92 | my $multi = $memc->get_multi(map { key(int(rand($max))) } (1..$max)); 93 | $stop->("get_multi"); 94 | } 95 | 96 | sub key { 97 | my $n = shift; 98 | $_ = sprintf("%04d", $n); 99 | if ($n % 2) { $_ .= "a"x20; } 100 | $_; 101 | } 102 | -------------------------------------------------------------------------------- /t/unixsocket.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Test::More tests => 3; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MemcachedTest; 8 | 9 | my $filename = "/tmp/memcachetest$$"; 10 | 11 | my $server = new_memcached("-s $filename"); 12 | my $sock = $server->sock; 13 | 14 | ok(-S $filename, "creating unix domain socket $filename"); 15 | 16 | # set foo (and should get it) 17 | print $sock "set foo 0 0 6\r\nfooval\r\n"; 18 | 19 | is(scalar <$sock>, "STORED\r\n", "stored foo"); 20 | mem_get_is($sock, "foo", "fooval"); 21 | 22 | unlink($filename); 23 | 24 | ## Just some basic stuff for now... 25 | -------------------------------------------------------------------------------- /t/vbucket1.cfg: -------------------------------------------------------------------------------- 1 | 11211 = { 2 | "hashAlgorithm": "CRC", 3 | "numReplicas": 0, 4 | "serverList": ["localhost:11311"], 5 | "vBucketMap": 6 | [ 7 | [0], 8 | [0], 9 | [0], 10 | [0] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /t/vbucket2.cfg: -------------------------------------------------------------------------------- 1 | 11211 = { 2 | "hashAlgorithm": "CRC", 3 | "numReplicas": 1, 4 | "serverList": ["localhost:11311", "localhost:11312"], 5 | "vBucketMap": 6 | [ 7 | [0, 1], 8 | [1, 0] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /t/vbucket_rest1.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "vBucketServerMap": { 3 | "hashAlgorithm": "CRC", 4 | "numReplicas": 1, 5 | "serverList": ["localhost:11311", "localhost:11312"], 6 | "vBucketMap": 7 | [ 8 | [0, 1], 9 | [1, 0] 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /t/vbucket_rest2.cfg: -------------------------------------------------------------------------------- 1 | {"name":"default","uri":"/pools/default/buckets/default","streamingUri":"/pools/default/bucketsStreaming/default","flushCacheUri":"/pools/default/buckets/default/controller/doFlush","nodes":[{"clusterMembership":"inactiveAdded","status":"unhealthy","hostname":"127.0.0.1","version":"unknown","os":"unknown","ports":{"proxy":11213,"direct":11212},"uptime":"0","memoryTotal":0,"memoryFree":0,"mcdMemoryReserved":64,"mcdMemoryAllocated":0}],"stats":{"uri":"/pools/default/buckets/default/stats"},"vBucketServerMap":{"hashAlgorithm":"CRC","numReplicas":0,"serverList":["127.0.0.1:11212"],"vBucketMap":[[0],[0]]},"basicStats":{"cacheSize":64,"opsPerSec":0.0,"evictionsPerSec":0.0,"cachePercentUsed":0.0}} 2 | -------------------------------------------------------------------------------- /t/whitespace.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use FindBin qw($Bin); 4 | our @files; 5 | 6 | BEGIN { 7 | chdir "$Bin/.." or die; 8 | @files = grep {! /^config.h$/ } (glob("*.h"), glob("*.c"), glob("*.ac"), 9 | "memcached.spec.in"); 10 | } 11 | use Test::More tests => scalar(@files); 12 | 13 | foreach my $f (@files) { 14 | open(my $fh, $f) or die "Cannot open $f: $!"; 15 | my $before = do { local $/; <$fh>; }; 16 | close ($fh); 17 | my $after = $before; 18 | $after =~ s/\t/ /g; 19 | $after =~ s/ +$//mg; 20 | $after .= "\n" unless $after =~ /\n$/; 21 | ok ($after eq $before, "$f (see devtools/clean-whitespace.pl)"); 22 | } 23 | -------------------------------------------------------------------------------- /timedrun.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | static int caught = 0; 11 | 12 | static void caught_signal(int which) 13 | { 14 | caught = which; 15 | } 16 | 17 | static int wait_for_process(pid_t pid) 18 | { 19 | int rv = EX_SOFTWARE; 20 | int stats = 0; 21 | int i = 0; 22 | struct sigaction sig_handler; 23 | 24 | sig_handler.sa_handler = caught_signal; 25 | sig_handler.sa_flags = 0; 26 | 27 | sigaction(SIGALRM, &sig_handler, NULL); 28 | sigaction(SIGHUP, &sig_handler, NULL); 29 | sigaction(SIGINT, &sig_handler, NULL); 30 | sigaction(SIGTERM, &sig_handler, NULL); 31 | sigaction(SIGPIPE, &sig_handler, NULL); 32 | 33 | /* Loop forever waiting for the process to quit */ 34 | for (i = 0; ;i++) { 35 | pid_t p = waitpid(pid, &stats, 0); 36 | if (p == pid) { 37 | /* child exited. Let's get out of here */ 38 | rv = WIFEXITED(stats) ? 39 | WEXITSTATUS(stats) : 40 | (0x80 | WTERMSIG(stats)); 41 | break; 42 | } else { 43 | int sig = 0; 44 | switch (i) { 45 | case 0: 46 | /* On the first iteration, pass the signal through */ 47 | sig = caught > 0 ? caught : SIGTERM; 48 | break; 49 | case 1: 50 | sig = SIGTERM; 51 | break; 52 | default: 53 | sig = SIGKILL; 54 | break; 55 | } 56 | if (kill(pid, sig) < 0) { 57 | /* Kill failed. Must have lost the process. :/ */ 58 | perror("lost child when trying to kill"); 59 | } 60 | /* Wait up to 5 seconds for the pid */ 61 | alarm(5); 62 | } 63 | } 64 | return rv; 65 | } 66 | 67 | static int spawn_and_wait(int argc, char **argv) 68 | { 69 | int rv = EX_SOFTWARE; 70 | pid_t pid = fork(); 71 | 72 | assert(argc > 1); 73 | 74 | switch (pid) { 75 | case -1: 76 | perror("fork"); 77 | rv = EX_OSERR; 78 | break; /* NOTREACHED */ 79 | case 0: 80 | execvp(argv[0], argv); 81 | perror("exec"); 82 | rv = EX_SOFTWARE; 83 | break; /* NOTREACHED */ 84 | default: 85 | rv = wait_for_process(pid); 86 | } 87 | return rv; 88 | } 89 | 90 | int main(int argc, char **argv) 91 | { 92 | int naptime = 0; 93 | assert(argc > 2); 94 | 95 | naptime = atoi(argv[1]); 96 | assert(naptime > 0 && naptime < 1800); 97 | 98 | alarm(naptime); 99 | 100 | return spawn_and_wait(argc+2, argv+2); 101 | } 102 | -------------------------------------------------------------------------------- /trace.h: -------------------------------------------------------------------------------- 1 | #ifndef TRACE_H 2 | #define TRACE_H 3 | 4 | #ifdef ENABLE_DTRACE 5 | #include "memcached_dtrace.h" 6 | #else 7 | #define MEMCACHED_ASSOC_DELETE(arg0, arg1, arg2) 8 | #define MEMCACHED_ASSOC_DELETE_ENABLED() (0) 9 | #define MEMCACHED_ASSOC_FIND(arg0, arg1, arg2) 10 | #define MEMCACHED_ASSOC_FIND_ENABLED() (0) 11 | #define MEMCACHED_ASSOC_INSERT(arg0, arg1, arg2) 12 | #define MEMCACHED_ASSOC_INSERT_ENABLED() (0) 13 | #define MEMCACHED_COMMAND_ADD(arg0, arg1, arg2, arg3, arg4) 14 | #define MEMCACHED_COMMAND_ADD_ENABLED() (0) 15 | #define MEMCACHED_COMMAND_APPEND(arg0, arg1, arg2, arg3, arg4) 16 | #define MEMCACHED_COMMAND_APPEND_ENABLED() (0) 17 | #define MEMCACHED_COMMAND_CAS(arg0, arg1, arg2, arg3, arg4) 18 | #define MEMCACHED_COMMAND_CAS_ENABLED() (0) 19 | #define MEMCACHED_COMMAND_DECR(arg0, arg1, arg2, arg3) 20 | #define MEMCACHED_COMMAND_DECR_ENABLED() (0) 21 | #define MEMCACHED_COMMAND_DELETE(arg0, arg1, arg2) 22 | #define MEMCACHED_COMMAND_DELETE_ENABLED() (0) 23 | #define MEMCACHED_COMMAND_GET(arg0, arg1, arg2, arg3, arg4) 24 | #define MEMCACHED_COMMAND_GET_ENABLED() (0) 25 | #define MEMCACHED_COMMAND_INCR(arg0, arg1, arg2, arg3) 26 | #define MEMCACHED_COMMAND_INCR_ENABLED() (0) 27 | #define MEMCACHED_COMMAND_PREPEND(arg0, arg1, arg2, arg3, arg4) 28 | #define MEMCACHED_COMMAND_PREPEND_ENABLED() (0) 29 | #define MEMCACHED_COMMAND_REPLACE(arg0, arg1, arg2, arg3, arg4) 30 | #define MEMCACHED_COMMAND_REPLACE_ENABLED() (0) 31 | #define MEMCACHED_COMMAND_SET(arg0, arg1, arg2, arg3, arg4) 32 | #define MEMCACHED_COMMAND_SET_ENABLED() (0) 33 | #define MEMCACHED_CONN_ALLOCATE(arg0) 34 | #define MEMCACHED_CONN_ALLOCATE_ENABLED() (0) 35 | #define MEMCACHED_CONN_CREATE(arg0) 36 | #define MEMCACHED_CONN_CREATE_ENABLED() (0) 37 | #define MEMCACHED_CONN_DESTROY(arg0) 38 | #define MEMCACHED_CONN_DESTROY_ENABLED() (0) 39 | #define MEMCACHED_CONN_DISPATCH(arg0, arg1) 40 | #define MEMCACHED_CONN_DISPATCH_ENABLED() (0) 41 | #define MEMCACHED_CONN_RELEASE(arg0) 42 | #define MEMCACHED_CONN_RELEASE_ENABLED() (0) 43 | #define MEMCACHED_ITEM_LINK(arg0, arg1, arg2) 44 | #define MEMCACHED_ITEM_LINK_ENABLED() (0) 45 | #define MEMCACHED_ITEM_REMOVE(arg0, arg1, arg2) 46 | #define MEMCACHED_ITEM_REMOVE_ENABLED() (0) 47 | #define MEMCACHED_ITEM_REPLACE(arg0, arg1, arg2, arg3, arg4, arg5) 48 | #define MEMCACHED_ITEM_REPLACE_ENABLED() (0) 49 | #define MEMCACHED_ITEM_UNLINK(arg0, arg1, arg2) 50 | #define MEMCACHED_ITEM_UNLINK_ENABLED() (0) 51 | #define MEMCACHED_ITEM_UPDATE(arg0, arg1, arg2) 52 | #define MEMCACHED_ITEM_UPDATE_ENABLED() (0) 53 | #define MEMCACHED_PROCESS_COMMAND_END(arg0, arg1, arg2) 54 | #define MEMCACHED_PROCESS_COMMAND_END_ENABLED() (0) 55 | #define MEMCACHED_PROCESS_COMMAND_START(arg0, arg1, arg2) 56 | #define MEMCACHED_PROCESS_COMMAND_START_ENABLED() (0) 57 | #define MEMCACHED_SLABS_ALLOCATE(arg0, arg1, arg2, arg3) 58 | #define MEMCACHED_SLABS_ALLOCATE_ENABLED() (0) 59 | #define MEMCACHED_SLABS_ALLOCATE_FAILED(arg0, arg1) 60 | #define MEMCACHED_SLABS_ALLOCATE_FAILED_ENABLED() (0) 61 | #define MEMCACHED_SLABS_FREE(arg0, arg1, arg2) 62 | #define MEMCACHED_SLABS_FREE_ENABLED() (0) 63 | #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE(arg0) 64 | #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_ENABLED() (0) 65 | #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(arg0) 66 | #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED_ENABLED() (0) 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrappers around strtoull/strtoll that are safer and easier to 3 | * use. For tests and assumptions, see internal_tests.c. 4 | * 5 | * str a NULL-terminated base decimal 10 unsigned integer 6 | * out out parameter, if conversion succeeded 7 | * 8 | * returns true if conversion succeeded. 9 | */ 10 | bool safe_strtoull(const char *str, uint64_t *out); 11 | bool safe_strtoll(const char *str, int64_t *out); 12 | bool safe_strtoul(const char *str, uint32_t *out); 13 | bool safe_strtol(const char *str, int32_t *out); 14 | 15 | /* This was stolen from the glibc docs. 16 | 17 | Why they'd write documentation to show how to do this vs. just 18 | provide the function is unclear. 19 | */ 20 | int timeval_subtract(struct timeval *result, 21 | struct timeval *x, struct timeval *y); 22 | 23 | /** 24 | * Convert a timeval to a simple double. 25 | * 26 | * This is generally useful for deltas. 27 | */ 28 | double timeval_to_double(struct timeval tv); 29 | 30 | struct moxi_stats { 31 | double min; 32 | double max; 33 | double avg; 34 | double stddev; 35 | double ninetyfifth; 36 | }; 37 | 38 | /** 39 | * Compute some statistics over a sequence. 40 | * 41 | * @param out accumulated stats for input values 42 | * @param vals input values (note: these will be reordered) 43 | * @param num_values the number of values to be processed 44 | */ 45 | void compute_stats(struct moxi_stats *out, double *vals, int num_vals); 46 | 47 | /* should be fixed in libconflate instead */ 48 | #ifdef __gcc_attribute__ 49 | #undef __gcc_attribute__ 50 | #endif 51 | 52 | #ifdef __GCC 53 | # define __gcc_attribute__ __attribute__ 54 | #else 55 | # define __gcc_attribute__(x) 56 | #endif 57 | 58 | /** 59 | * Vararg variant of perror that makes for more useful error messages 60 | * when reporting with parameters. 61 | * 62 | * @param fmt a printf format 63 | */ 64 | void vperror(const char *fmt, ...) 65 | __gcc_attribute__ ((format (printf, 1, 2))); 66 | 67 | #undef __gcc_attribute__ 68 | 69 | uint64_t ntohll(uint64_t value); 70 | uint64_t htonll(uint64_t value); 71 | -------------------------------------------------------------------------------- /version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if git describe | sed s/-/./g > version.num.tmp 4 | then 5 | mv version.num.tmp version.num 6 | echo "m4_define([VERSION_NUMBER], [`tr -d '\n' < version.num`])" \ 7 | > version.m4 8 | sed s/@VERSION@/`cat version.num`/ < memcached.spec.in > memcached.spec 9 | else 10 | rm version.num.tmp 11 | fi 12 | -------------------------------------------------------------------------------- /work.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | #ifndef WORK_H 4 | #define WORK_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef struct work_item work_item; 13 | typedef struct work_queue work_queue; 14 | typedef struct work_collect work_collect; 15 | 16 | struct work_item { 17 | void (*func)(void *data0, void *data1); 18 | void *data0; 19 | void *data1; 20 | work_item *next; 21 | }; 22 | 23 | struct work_queue { 24 | int send_fd; // Pipe to notify thread. 25 | int recv_fd; 26 | 27 | work_item *work_head; 28 | work_item *work_tail; 29 | 30 | uint64_t num_items; // Current number of items in queue. 31 | uint64_t tot_sends; 32 | uint64_t tot_recvs; 33 | 34 | struct event_base *event_base; 35 | struct event event; 36 | 37 | pthread_mutex_t work_lock; 38 | }; 39 | 40 | struct work_collect { 41 | int count; 42 | 43 | void *data; 44 | 45 | pthread_mutex_t collect_lock; 46 | pthread_cond_t collect_cond; // Signaled when count drops to 0. 47 | }; 48 | 49 | bool work_queue_init(work_queue *m, struct event_base *base); 50 | 51 | bool work_send(work_queue *m, 52 | void (*func)(void *data0, void *data1), 53 | void *data0, void *data1); 54 | 55 | void work_recv(int fd, short which, void *arg); 56 | 57 | void work_collect_init(work_collect *c, int count, void *data); 58 | void work_collect_wait(work_collect *c); 59 | void work_collect_count(work_collect *c, int count); 60 | void work_collect_one(work_collect *c); 61 | 62 | #endif // WORK_H 63 | --------------------------------------------------------------------------------