couchbase-memcached 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +2 -0
- data/BENCHMARKS +134 -0
- data/CHANGELOG +127 -0
- data/LICENSE +184 -0
- data/Manifest +535 -0
- data/README +118 -0
- data/Rakefile +83 -0
- data/TODO +4 -0
- data/couchbase-memcached.gemspec +33 -0
- data/ext/extconf-make.rb +25 -0
- data/ext/extconf.rb +91 -0
- data/ext/libmemcached-0.50/AUTHORS +11 -0
- data/ext/libmemcached-0.50/COPYING +33 -0
- data/ext/libmemcached-0.50/ChangeLog +392 -0
- data/ext/libmemcached-0.50/Makefile.am +114 -0
- data/ext/libmemcached-0.50/Makefile.in +4232 -0
- data/ext/libmemcached-0.50/NEWS +1 -0
- data/ext/libmemcached-0.50/README +43 -0
- data/ext/libmemcached-0.50/README.FIRST +31 -0
- data/ext/libmemcached-0.50/README.win32 +25 -0
- data/ext/libmemcached-0.50/THANKS +14 -0
- data/ext/libmemcached-0.50/TODO +11 -0
- data/ext/libmemcached-0.50/aclocal.m4 +1077 -0
- data/ext/libmemcached-0.50/clients/client_options.h +45 -0
- data/ext/libmemcached-0.50/clients/execute.cc +131 -0
- data/ext/libmemcached-0.50/clients/execute.h +30 -0
- data/ext/libmemcached-0.50/clients/generator.cc +96 -0
- data/ext/libmemcached-0.50/clients/generator.h +36 -0
- data/ext/libmemcached-0.50/clients/include.am +116 -0
- data/ext/libmemcached-0.50/clients/memaslap.c +908 -0
- data/ext/libmemcached-0.50/clients/memcapable.cc +2094 -0
- data/ext/libmemcached-0.50/clients/memcat.cc +242 -0
- data/ext/libmemcached-0.50/clients/memcp.cc +317 -0
- data/ext/libmemcached-0.50/clients/memdump.cc +183 -0
- data/ext/libmemcached-0.50/clients/memerror.cc +102 -0
- data/ext/libmemcached-0.50/clients/memflush.cc +154 -0
- data/ext/libmemcached-0.50/clients/memparse.cc +68 -0
- data/ext/libmemcached-0.50/clients/memrm.cc +177 -0
- data/ext/libmemcached-0.50/clients/memslap.cc +495 -0
- data/ext/libmemcached-0.50/clients/memstat.cc +349 -0
- data/ext/libmemcached-0.50/clients/ms_atomic.h +69 -0
- data/ext/libmemcached-0.50/clients/ms_conn.c +3413 -0
- data/ext/libmemcached-0.50/clients/ms_conn.h +241 -0
- data/ext/libmemcached-0.50/clients/ms_memslap.h +132 -0
- data/ext/libmemcached-0.50/clients/ms_setting.c +1068 -0
- data/ext/libmemcached-0.50/clients/ms_setting.h +181 -0
- data/ext/libmemcached-0.50/clients/ms_sigsegv.c +126 -0
- data/ext/libmemcached-0.50/clients/ms_sigsegv.h +34 -0
- data/ext/libmemcached-0.50/clients/ms_stats.c +307 -0
- data/ext/libmemcached-0.50/clients/ms_stats.h +69 -0
- data/ext/libmemcached-0.50/clients/ms_task.c +1114 -0
- data/ext/libmemcached-0.50/clients/ms_task.h +94 -0
- data/ext/libmemcached-0.50/clients/ms_thread.c +351 -0
- data/ext/libmemcached-0.50/clients/ms_thread.h +78 -0
- data/ext/libmemcached-0.50/clients/utilities.cc +231 -0
- data/ext/libmemcached-0.50/clients/utilities.h +64 -0
- data/ext/libmemcached-0.50/config.h.in +647 -0
- data/ext/libmemcached-0.50/config/autorun.sh +126 -0
- data/ext/libmemcached-0.50/config/compile +143 -0
- data/ext/libmemcached-0.50/config/config.guess +1517 -0
- data/ext/libmemcached-0.50/config/config.rpath +666 -0
- data/ext/libmemcached-0.50/config/config.sub +1760 -0
- data/ext/libmemcached-0.50/config/depcomp +630 -0
- data/ext/libmemcached-0.50/config/install-sh +520 -0
- data/ext/libmemcached-0.50/config/ltmain.sh +9642 -0
- data/ext/libmemcached-0.50/config/missing +376 -0
- data/ext/libmemcached-0.50/config/pandora-plugin +752 -0
- data/ext/libmemcached-0.50/config/uncrustify.cfg +1112 -0
- data/ext/libmemcached-0.50/configure +27103 -0
- data/ext/libmemcached-0.50/configure.ac +186 -0
- data/ext/libmemcached-0.50/docs/conf.py.in +354 -0
- data/ext/libmemcached-0.50/docs/include.am +240 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_clone.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_crc32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_create.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_64.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_64.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_free.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_functions.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_hsieh.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_is_allocated.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_jenkins.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_md5.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_murmur.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_value.3 +66 -0
- data/ext/libmemcached-0.50/docs/man/libhashkit.3 +57 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached.3 +208 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_check_configuration.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_configuration.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_examples.3 +144 -0
- data/ext/libmemcached-0.50/docs/man/libmemcachedutil.3 +68 -0
- data/ext/libmemcached-0.50/docs/man/memaslap.1 +1222 -0
- data/ext/libmemcached-0.50/docs/man/memcached.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/memcached_add.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_add_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_analyze.3 +77 -0
- data/ext/libmemcached-0.50/docs/man/memcached_append.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_append_by_key.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_behavior_get.3 +333 -0
- data/ext/libmemcached-0.50/docs/man/memcached_behavior_set.3 +333 -0
- data/ext/libmemcached-0.50/docs/man/memcached_callback_get.3 +159 -0
- data/ext/libmemcached-0.50/docs/man/memcached_callback_set.3 +159 -0
- data/ext/libmemcached-0.50/docs/man/memcached_cas.3 +91 -0
- data/ext/libmemcached-0.50/docs/man/memcached_cas_by_key.3 +91 -0
- data/ext/libmemcached-0.50/docs/man/memcached_clone.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_create.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_decrement.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_decrement_with_initial.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_delete.3 +83 -0
- data/ext/libmemcached-0.50/docs/man/memcached_delete_by_key.3 +83 -0
- data/ext/libmemcached-0.50/docs/man/memcached_destroy_sasl_auth_data.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_dump.3 +77 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch_execute.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch_result.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_flush_buffers.3 +72 -0
- data/ext/libmemcached-0.50/docs/man/memcached_free.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_generate_hash.3 +85 -0
- data/ext/libmemcached-0.50/docs/man/memcached_generate_hash_value.3 +85 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_memory_allocators.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_sasl_callbacks.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_user_data.3 +79 -0
- data/ext/libmemcached-0.50/docs/man/memcached_increment.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_increment_with_initial.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_lib_version.3 +76 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_execute.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_execute_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_get.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_set.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_create.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_destroy.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_pop.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_push.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_st.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_prepend.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_prepend_by_key.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_quit.3 +74 -0
- data/ext/libmemcached-0.50/docs/man/memcached_replace.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_replace_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_sasl_set_auth_data.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_add.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_count.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_cursor.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_append.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_count.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_free.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_push.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_servers_parse.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_memory_allocators.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_sasl_callbacks.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_user_data.3 +79 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_execute.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_get_keys.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_get_value.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_servername.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_strerror.3 +69 -0
- data/ext/libmemcached-0.50/docs/man/memcached_verbosity.3 +66 -0
- data/ext/libmemcached-0.50/docs/man/memcached_version.3 +76 -0
- data/ext/libmemcached-0.50/docs/man/memcapable.1 +92 -0
- data/ext/libmemcached-0.50/docs/man/memcat.1 +71 -0
- data/ext/libmemcached-0.50/docs/man/memcp.1 +77 -0
- data/ext/libmemcached-0.50/docs/man/memdump.1 +66 -0
- data/ext/libmemcached-0.50/docs/man/memerror.1 +65 -0
- data/ext/libmemcached-0.50/docs/man/memflush.1 +73 -0
- data/ext/libmemcached-0.50/docs/man/memrm.1 +72 -0
- data/ext/libmemcached-0.50/docs/man/memslap.1 +59 -0
- data/ext/libmemcached-0.50/docs/man/memstat.1 +70 -0
- data/ext/libmemcached-0.50/example/include.am +24 -0
- data/ext/libmemcached-0.50/example/interface_v0.c +594 -0
- data/ext/libmemcached-0.50/example/interface_v1.c +411 -0
- data/ext/libmemcached-0.50/example/memcached_light.c +474 -0
- data/ext/libmemcached-0.50/example/memcached_light.h +7 -0
- data/ext/libmemcached-0.50/example/storage.c +172 -0
- data/ext/libmemcached-0.50/example/storage.h +27 -0
- data/ext/libmemcached-0.50/example/storage_innodb.c +535 -0
- data/ext/libmemcached-0.50/libhashkit/algorithm.cc +69 -0
- data/ext/libmemcached-0.50/libhashkit/algorithm.h +96 -0
- data/ext/libmemcached-0.50/libhashkit/behavior.cc +9 -0
- data/ext/libmemcached-0.50/libhashkit/behavior.h +26 -0
- data/ext/libmemcached-0.50/libhashkit/common.h +33 -0
- data/ext/libmemcached-0.50/libhashkit/configure.h.in +19 -0
- data/ext/libmemcached-0.50/libhashkit/crc32.cc +86 -0
- data/ext/libmemcached-0.50/libhashkit/digest.cc +62 -0
- data/ext/libmemcached-0.50/libhashkit/digest.h +30 -0
- data/ext/libmemcached-0.50/libhashkit/fnv.cc +75 -0
- data/ext/libmemcached-0.50/libhashkit/function.cc +156 -0
- data/ext/libmemcached-0.50/libhashkit/function.h +44 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.cc +100 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.h +95 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.hpp +97 -0
- data/ext/libmemcached-0.50/libhashkit/hsieh.cc +70 -0
- data/ext/libmemcached-0.50/libhashkit/include.am +69 -0
- data/ext/libmemcached-0.50/libhashkit/jenkins.cc +214 -0
- data/ext/libmemcached-0.50/libhashkit/ketama.cc +164 -0
- data/ext/libmemcached-0.50/libhashkit/md5.cc +367 -0
- data/ext/libmemcached-0.50/libhashkit/murmur.cc +77 -0
- data/ext/libmemcached-0.50/libhashkit/one_at_a_time.cc +34 -0
- data/ext/libmemcached-0.50/libhashkit/str_algorithm.cc +58 -0
- data/ext/libmemcached-0.50/libhashkit/str_algorithm.h +48 -0
- data/ext/libmemcached-0.50/libhashkit/strerror.cc +25 -0
- data/ext/libmemcached-0.50/libhashkit/strerror.h +23 -0
- data/ext/libmemcached-0.50/libhashkit/types.h +90 -0
- data/ext/libmemcached-0.50/libhashkit/visibility.h +48 -0
- data/ext/libmemcached-0.50/libmemcached/allocators.cc +119 -0
- data/ext/libmemcached-0.50/libmemcached/allocators.h +87 -0
- data/ext/libmemcached-0.50/libmemcached/analyze.cc +110 -0
- data/ext/libmemcached-0.50/libmemcached/analyze.h +66 -0
- data/ext/libmemcached-0.50/libmemcached/array.c +128 -0
- data/ext/libmemcached-0.50/libmemcached/array.h +75 -0
- data/ext/libmemcached-0.50/libmemcached/auto.cc +383 -0
- data/ext/libmemcached-0.50/libmemcached/auto.h +111 -0
- data/ext/libmemcached-0.50/libmemcached/basic_string.h +55 -0
- data/ext/libmemcached-0.50/libmemcached/behavior.cc +590 -0
- data/ext/libmemcached-0.50/libmemcached/behavior.h +86 -0
- data/ext/libmemcached-0.50/libmemcached/byteorder.cc +90 -0
- data/ext/libmemcached-0.50/libmemcached/byteorder.h +52 -0
- data/ext/libmemcached-0.50/libmemcached/callback.cc +160 -0
- data/ext/libmemcached-0.50/libmemcached/callback.h +61 -0
- data/ext/libmemcached-0.50/libmemcached/common.h +182 -0
- data/ext/libmemcached-0.50/libmemcached/configure.h.in +52 -0
- data/ext/libmemcached-0.50/libmemcached/connect.cc +626 -0
- data/ext/libmemcached-0.50/libmemcached/constants.h +167 -0
- data/ext/libmemcached-0.50/libmemcached/delete.cc +266 -0
- data/ext/libmemcached-0.50/libmemcached/delete.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/do.cc +100 -0
- data/ext/libmemcached-0.50/libmemcached/do.hpp +49 -0
- data/ext/libmemcached-0.50/libmemcached/dump.cc +107 -0
- data/ext/libmemcached-0.50/libmemcached/dump.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/error.cc +419 -0
- data/ext/libmemcached-0.50/libmemcached/error.h +61 -0
- data/ext/libmemcached-0.50/libmemcached/error.hpp +87 -0
- data/ext/libmemcached-0.50/libmemcached/exception.hpp +63 -0
- data/ext/libmemcached-0.50/libmemcached/fetch.cc +267 -0
- data/ext/libmemcached-0.50/libmemcached/fetch.h +53 -0
- data/ext/libmemcached-0.50/libmemcached/flush.cc +149 -0
- data/ext/libmemcached-0.50/libmemcached/flush.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/flush_buffers.cc +66 -0
- data/ext/libmemcached-0.50/libmemcached/flush_buffers.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/get.cc +842 -0
- data/ext/libmemcached-0.50/libmemcached/get.h +135 -0
- data/ext/libmemcached-0.50/libmemcached/hash.cc +178 -0
- data/ext/libmemcached-0.50/libmemcached/hash.h +68 -0
- data/ext/libmemcached-0.50/libmemcached/hosts.cc +516 -0
- data/ext/libmemcached-0.50/libmemcached/include.am +183 -0
- data/ext/libmemcached-0.50/libmemcached/initialize_query.cc +70 -0
- data/ext/libmemcached-0.50/libmemcached/initialize_query.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/internal.h +46 -0
- data/ext/libmemcached-0.50/libmemcached/io.cc +920 -0
- data/ext/libmemcached-0.50/libmemcached/io.h +119 -0
- data/ext/libmemcached-0.50/libmemcached/is.h +48 -0
- data/ext/libmemcached-0.50/libmemcached/key.cc +23 -0
- data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.d +30 -0
- data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.h +118 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.cc +437 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.h +214 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.hpp +799 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/README.txt +7 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/protocol_binary.h +726 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/vbucket.h +26 -0
- data/ext/libmemcached-0.50/libmemcached/memcached_util.h +44 -0
- data/ext/libmemcached-0.50/libmemcached/memory.h +79 -0
- data/ext/libmemcached-0.50/libmemcached/options.cc +178 -0
- data/ext/libmemcached-0.50/libmemcached/options.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/options.hpp +56 -0
- data/ext/libmemcached-0.50/libmemcached/options/context.h +151 -0
- data/ext/libmemcached-0.50/libmemcached/options/include.am +19 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.am +0 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.cc +2324 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.h +122 -0
- data/ext/libmemcached-0.50/libmemcached/options/scanner.cc +3203 -0
- data/ext/libmemcached-0.50/libmemcached/options/scanner.h +479 -0
- data/ext/libmemcached-0.50/libmemcached/options/server.h +60 -0
- data/ext/libmemcached-0.50/libmemcached/options/symbol.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/parse.cc +110 -0
- data/ext/libmemcached-0.50/libmemcached/parse.h +23 -0
- data/ext/libmemcached-0.50/libmemcached/platform.h +56 -0
- data/ext/libmemcached-0.50/libmemcached/prefix_key.cc +65 -0
- data/ext/libmemcached-0.50/libmemcached/prefix_key.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.c +963 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.h +40 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.c +1121 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.h +47 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/cache.c +149 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/cache.h +116 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/callback.h +418 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/common.h +163 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/include.am +26 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/pedantic.c +202 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/protocol_handler.c +365 -0
- data/ext/libmemcached-0.50/libmemcached/protocol_handler.h +215 -0
- data/ext/libmemcached-0.50/libmemcached/purge.cc +90 -0
- data/ext/libmemcached-0.50/libmemcached/quit.cc +139 -0
- data/ext/libmemcached-0.50/libmemcached/quit.h +55 -0
- data/ext/libmemcached-0.50/libmemcached/response.cc +619 -0
- data/ext/libmemcached-0.50/libmemcached/response.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/result.cc +173 -0
- data/ext/libmemcached-0.50/libmemcached/result.h +100 -0
- data/ext/libmemcached-0.50/libmemcached/return.h +98 -0
- data/ext/libmemcached-0.50/libmemcached/sasl.c +408 -0
- data/ext/libmemcached-0.50/libmemcached/sasl.h +86 -0
- data/ext/libmemcached-0.50/libmemcached/server.cc +351 -0
- data/ext/libmemcached-0.50/libmemcached/server.h +169 -0
- data/ext/libmemcached-0.50/libmemcached/server_list.cc +88 -0
- data/ext/libmemcached-0.50/libmemcached/server_list.h +77 -0
- data/ext/libmemcached-0.50/libmemcached/stats.cc +623 -0
- data/ext/libmemcached-0.50/libmemcached/stats.h +96 -0
- data/ext/libmemcached-0.50/libmemcached/storage.cc +567 -0
- data/ext/libmemcached-0.50/libmemcached/storage.h +133 -0
- data/ext/libmemcached-0.50/libmemcached/strerror.cc +189 -0
- data/ext/libmemcached-0.50/libmemcached/strerror.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/string.cc +253 -0
- data/ext/libmemcached-0.50/libmemcached/string.h +121 -0
- data/ext/libmemcached-0.50/libmemcached/touch.cc +106 -0
- data/ext/libmemcached-0.50/libmemcached/touch.h +59 -0
- data/ext/libmemcached-0.50/libmemcached/types.h +117 -0
- data/ext/libmemcached-0.50/libmemcached/util.h +40 -0
- data/ext/libmemcached-0.50/libmemcached/util/flush.cc +61 -0
- data/ext/libmemcached-0.50/libmemcached/util/flush.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/util/include.am +34 -0
- data/ext/libmemcached-0.50/libmemcached/util/ping.cc +62 -0
- data/ext/libmemcached-0.50/libmemcached/util/ping.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/util/pool.cc +392 -0
- data/ext/libmemcached-0.50/libmemcached/util/pool.h +78 -0
- data/ext/libmemcached-0.50/libmemcached/util/version.cc +87 -0
- data/ext/libmemcached-0.50/libmemcached/util/version.h +53 -0
- data/ext/libmemcached-0.50/libmemcached/verbosity.cc +97 -0
- data/ext/libmemcached-0.50/libmemcached/verbosity.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/version.cc +214 -0
- data/ext/libmemcached-0.50/libmemcached/version.h +52 -0
- data/ext/libmemcached-0.50/libmemcached/virtual_bucket.c +118 -0
- data/ext/libmemcached-0.50/libmemcached/virtual_bucket.h +59 -0
- data/ext/libmemcached-0.50/libmemcached/visibility.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/watchpoint.h +110 -0
- data/ext/libmemcached-0.50/libtest/callbacks.h +21 -0
- data/ext/libmemcached-0.50/libtest/collection.h +19 -0
- data/ext/libmemcached-0.50/libtest/common.h +50 -0
- data/ext/libmemcached-0.50/libtest/core.h +11 -0
- data/ext/libmemcached-0.50/libtest/error.h +18 -0
- data/ext/libmemcached-0.50/libtest/failed.h +52 -0
- data/ext/libmemcached-0.50/libtest/framework.cc +57 -0
- data/ext/libmemcached-0.50/libtest/framework.h +137 -0
- data/ext/libmemcached-0.50/libtest/get.h +22 -0
- data/ext/libmemcached-0.50/libtest/include.am +52 -0
- data/ext/libmemcached-0.50/libtest/runner.h +19 -0
- data/ext/libmemcached-0.50/libtest/server.c +355 -0
- data/ext/libmemcached-0.50/libtest/server.h +43 -0
- data/ext/libmemcached-0.50/libtest/stats.h +30 -0
- data/ext/libmemcached-0.50/libtest/strerror.h +14 -0
- data/ext/libmemcached-0.50/libtest/test.cc +319 -0
- data/ext/libmemcached-0.50/libtest/test.h +162 -0
- data/ext/libmemcached-0.50/libtest/test.hpp +46 -0
- data/ext/libmemcached-0.50/libtest/visibility.h +69 -0
- data/ext/libmemcached-0.50/m4/ac_cxx_header_stdcxx_98.m4 +83 -0
- data/ext/libmemcached-0.50/m4/acx_pthread.m4 +271 -0
- data/ext/libmemcached-0.50/m4/byteorder.m4 +19 -0
- data/ext/libmemcached-0.50/m4/deprecated.m4 +17 -0
- data/ext/libmemcached-0.50/m4/eagain.m4 +28 -0
- data/ext/libmemcached-0.50/m4/enable_utillib.m4 +16 -0
- data/ext/libmemcached-0.50/m4/gettext.m4 +379 -0
- data/ext/libmemcached-0.50/m4/hsieh.m4 +18 -0
- data/ext/libmemcached-0.50/m4/iconv.m4 +214 -0
- data/ext/libmemcached-0.50/m4/lib-ld.m4 +110 -0
- data/ext/libmemcached-0.50/m4/lib-link.m4 +767 -0
- data/ext/libmemcached-0.50/m4/lib-prefix.m4 +221 -0
- data/ext/libmemcached-0.50/m4/libtool.m4 +7851 -0
- data/ext/libmemcached-0.50/m4/ltoptions.m4 +369 -0
- data/ext/libmemcached-0.50/m4/ltsugar.m4 +123 -0
- data/ext/libmemcached-0.50/m4/ltversion.m4 +23 -0
- data/ext/libmemcached-0.50/m4/lt~obsolete.m4 +98 -0
- data/ext/libmemcached-0.50/m4/memaslap.m4 +9 -0
- data/ext/libmemcached-0.50/m4/memcached.m4 +31 -0
- data/ext/libmemcached-0.50/m4/murmur.m4 +18 -0
- data/ext/libmemcached-0.50/m4/pandora_64bit.m4 +60 -0
- data/ext/libmemcached-0.50/m4/pandora_bison.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_canonical.m4 +418 -0
- data/ext/libmemcached-0.50/m4/pandora_check_compiler_version.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_check_cxx_standard.m4 +23 -0
- data/ext/libmemcached-0.50/m4/pandora_cinttypes.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_clock_gettime.m4 +15 -0
- data/ext/libmemcached-0.50/m4/pandora_compile_stdcxx_0x.m4 +103 -0
- data/ext/libmemcached-0.50/m4/pandora_cstdint.m4 +38 -0
- data/ext/libmemcached-0.50/m4/pandora_cxx_demangle.m4 +27 -0
- data/ext/libmemcached-0.50/m4/pandora_enable_dtrace.m4 +60 -0
- data/ext/libmemcached-0.50/m4/pandora_ensure_gcc_version.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_extensions.m4 +16 -0
- data/ext/libmemcached-0.50/m4/pandora_fdatasync.m4 +25 -0
- data/ext/libmemcached-0.50/m4/pandora_flex.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_have_better_malloc.m4 +66 -0
- data/ext/libmemcached-0.50/m4/pandora_have_boost.m4 +93 -0
- data/ext/libmemcached-0.50/m4/pandora_have_gcc_atomics.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_have_innodb.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libaio.m4 +56 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libavahi.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libbdb.m4 +40 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_date_time.m4 +46 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_filesystem.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_iostreams.m4 +49 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_options.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_regex.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_test.m4 +45 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_thread.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libcassandra.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libcurl.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libdl.m4 +51 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libdrizzle.m4 +61 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libevent.m4 +66 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libgearman.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libgtest.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libhaildb.m4 +43 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libhashkit.m4 +42 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libinnodb.m4 +64 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libldap.m4 +73 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libmemcached.m4 +106 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libmysqlclient.m4 +146 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libndbclient.m4 +80 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpcre.m4 +73 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpq.m4 +46 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpqxx.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libsqlite3.m4 +42 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libtokyocabinet.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libuuid.m4 +55 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libvbucket.m4 +40 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libxml2.m4 +52 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libz.m4 +51 -0
- data/ext/libmemcached-0.50/m4/pandora_have_protobuf.m4 +82 -0
- data/ext/libmemcached-0.50/m4/pandora_have_sasl.m4 +133 -0
- data/ext/libmemcached-0.50/m4/pandora_have_thrift.m4 +45 -0
- data/ext/libmemcached-0.50/m4/pandora_header_assert.m4 +23 -0
- data/ext/libmemcached-0.50/m4/pandora_header_stdcxx_98.m4 +83 -0
- data/ext/libmemcached-0.50/m4/pandora_intltool.m4 +225 -0
- data/ext/libmemcached-0.50/m4/pandora_libtool.m4 +25 -0
- data/ext/libmemcached-0.50/m4/pandora_optimize.m4 +75 -0
- data/ext/libmemcached-0.50/m4/pandora_platform.m4 +117 -0
- data/ext/libmemcached-0.50/m4/pandora_plugins.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_print_callstack.m4 +61 -0
- data/ext/libmemcached-0.50/m4/pandora_pthread.m4 +258 -0
- data/ext/libmemcached-0.50/m4/pandora_python3_devel.m4 +236 -0
- data/ext/libmemcached-0.50/m4/pandora_run_cpplint.m4 +8 -0
- data/ext/libmemcached-0.50/m4/pandora_sasl.m4 +133 -0
- data/ext/libmemcached-0.50/m4/pandora_shared_ptr.m4 +59 -0
- data/ext/libmemcached-0.50/m4/pandora_stack_direction.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_stl_hash.m4 +94 -0
- data/ext/libmemcached-0.50/m4/pandora_swig.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_use_pipe.m4 +36 -0
- data/ext/libmemcached-0.50/m4/pandora_vc_build.m4 +168 -0
- data/ext/libmemcached-0.50/m4/pandora_version.m4 +11 -0
- data/ext/libmemcached-0.50/m4/pandora_visibility.m4 +75 -0
- data/ext/libmemcached-0.50/m4/pandora_warnings.m4 +447 -0
- data/ext/libmemcached-0.50/m4/pandora_with_gettext.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_with_lua.m4 +55 -0
- data/ext/libmemcached-0.50/m4/pandora_with_memcached.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_with_perl.m4 +81 -0
- data/ext/libmemcached-0.50/m4/pandora_with_php.m4 +56 -0
- data/ext/libmemcached-0.50/m4/pandora_with_python.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_with_python3.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_with_r.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_with_ruby.m4 +79 -0
- data/ext/libmemcached-0.50/m4/pandora_with_valgrind.m4 +17 -0
- data/ext/libmemcached-0.50/m4/pkg.m4 +157 -0
- data/ext/libmemcached-0.50/m4/po.m4 +449 -0
- data/ext/libmemcached-0.50/m4/progtest.m4 +92 -0
- data/ext/libmemcached-0.50/m4/protocol_binary.m4 +36 -0
- data/ext/libmemcached-0.50/m4/setsockopt.m4 +73 -0
- data/ext/libmemcached-0.50/m4/socket_send_flags.m4 +66 -0
- data/ext/libmemcached-0.50/poll/include.am +8 -0
- data/ext/libmemcached-0.50/poll/poll.c +77 -0
- data/ext/libmemcached-0.50/poll/poll.h +45 -0
- data/ext/libmemcached-0.50/support/include.am +11 -0
- data/ext/libmemcached-0.50/support/libmemcached-fc.spec.in +105 -0
- data/ext/libmemcached-0.50/support/libmemcached.pc.in +10 -0
- data/ext/libmemcached-0.50/support/libmemcached.spec.in +281 -0
- data/ext/libmemcached-0.50/support/set_benchmark.sh +5 -0
- data/ext/libmemcached-0.50/tests/atomsmasher.cc +295 -0
- data/ext/libmemcached-0.50/tests/basic.cc +134 -0
- data/ext/libmemcached-0.50/tests/basic.h +66 -0
- data/ext/libmemcached-0.50/tests/cpp_example.cc +195 -0
- data/ext/libmemcached-0.50/tests/deprecated.cc +72 -0
- data/ext/libmemcached-0.50/tests/deprecated.h +49 -0
- data/ext/libmemcached-0.50/tests/error_conditions.cc +63 -0
- data/ext/libmemcached-0.50/tests/error_conditions.h +48 -0
- data/ext/libmemcached-0.50/tests/hash_plus.cc +225 -0
- data/ext/libmemcached-0.50/tests/hash_results.h +127 -0
- data/ext/libmemcached-0.50/tests/hashkit_functions.cc +619 -0
- data/ext/libmemcached-0.50/tests/include.am +342 -0
- data/ext/libmemcached-0.50/tests/ketama_test_cases.h +121 -0
- data/ext/libmemcached-0.50/tests/ketama_test_cases_spy.h +118 -0
- data/ext/libmemcached-0.50/tests/libmemcached_world.h +205 -0
- data/ext/libmemcached-0.50/tests/mem_functions.cc +6648 -0
- data/ext/libmemcached-0.50/tests/mem_udp.cc +510 -0
- data/ext/libmemcached-0.50/tests/output_plus.res +5 -0
- data/ext/libmemcached-0.50/tests/parser.cc +599 -0
- data/ext/libmemcached-0.50/tests/parser.h +109 -0
- data/ext/libmemcached-0.50/tests/plus.cpp +240 -0
- data/ext/libmemcached-0.50/tests/pool.cc +78 -0
- data/ext/libmemcached-0.50/tests/pool.h +49 -0
- data/ext/libmemcached-0.50/tests/print.cc +58 -0
- data/ext/libmemcached-0.50/tests/print.h +51 -0
- data/ext/libmemcached-0.50/tests/replication.cc +333 -0
- data/ext/libmemcached-0.50/tests/replication.h +64 -0
- data/ext/libmemcached-0.50/tests/start.cc +29 -0
- data/ext/libmemcached-0.50/tests/string.cc +174 -0
- data/ext/libmemcached-0.50/tests/string.h +67 -0
- data/ext/libmemcached-0.50/tests/virtual_buckets.cc +143 -0
- data/ext/libmemcached-0.50/tests/virtual_buckets.h +51 -0
- data/ext/libmemcached-0.50/win32/include.am +11 -0
- data/ext/libmemcached-0.50/win32/wrappers.h +55 -0
- data/ext/rlibmemcached.i +263 -0
- data/ext/rlibmemcached_wrap.c +16732 -0
- data/lib/memcached.rb +32 -0
- data/lib/memcached/auth.rb +16 -0
- data/lib/memcached/behaviors.rb +77 -0
- data/lib/memcached/exceptions.rb +84 -0
- data/lib/memcached/experimental.rb +48 -0
- data/lib/memcached/memcached.rb +660 -0
- data/lib/memcached/rails.rb +133 -0
- data/test/profile/benchmark.rb +245 -0
- data/test/profile/c_profiler.rb +14 -0
- data/test/profile/exercise.rb +185 -0
- data/test/profile/rb_profiler.rb +21 -0
- data/test/profile/valgrind.rb +10 -0
- data/test/setup.rb +30 -0
- data/test/teardown.rb +0 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/binding_test.rb +8 -0
- data/test/unit/memcached_experimental_test.rb +274 -0
- data/test/unit/memcached_test.rb +1293 -0
- data/test/unit/rails_test.rb +122 -0
- metadata +650 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
2
|
+
/**
|
|
3
|
+
* This file contains an implementation of the callback interface for level 1
|
|
4
|
+
* in the protocol library. If you compare the implementation with the one
|
|
5
|
+
* in interface_v0.c you will see that this implementation is much easier and
|
|
6
|
+
* hides all of the protocol logic and let you focus on the application
|
|
7
|
+
* logic. One "problem" with this layer is that it is synchronous, so that
|
|
8
|
+
* you will not receive the next command before a answer to the previous
|
|
9
|
+
* command is being sent.
|
|
10
|
+
*/
|
|
11
|
+
#include "config.h"
|
|
12
|
+
#include <assert.h>
|
|
13
|
+
#include <sys/types.h>
|
|
14
|
+
#include <stdio.h>
|
|
15
|
+
#include <unistd.h>
|
|
16
|
+
#include <fcntl.h>
|
|
17
|
+
#include <errno.h>
|
|
18
|
+
#include <stdlib.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
|
|
21
|
+
#include <libmemcached/protocol_handler.h>
|
|
22
|
+
#include <libmemcached/byteorder.h>
|
|
23
|
+
#include "storage.h"
|
|
24
|
+
|
|
25
|
+
static protocol_binary_response_status add_handler(const void *cookie,
|
|
26
|
+
const void *key,
|
|
27
|
+
uint16_t keylen,
|
|
28
|
+
const void *data,
|
|
29
|
+
uint32_t datalen,
|
|
30
|
+
uint32_t flags,
|
|
31
|
+
uint32_t exptime,
|
|
32
|
+
uint64_t *cas)
|
|
33
|
+
{
|
|
34
|
+
(void)cookie;
|
|
35
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
36
|
+
struct item* item= get_item(key, keylen);
|
|
37
|
+
if (item == NULL)
|
|
38
|
+
{
|
|
39
|
+
item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
|
|
40
|
+
if (item == 0)
|
|
41
|
+
{
|
|
42
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
{
|
|
46
|
+
put_item(item);
|
|
47
|
+
*cas= item->cas;
|
|
48
|
+
release_item(item);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
{
|
|
53
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return rval;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static protocol_binary_response_status append_handler(const void *cookie,
|
|
60
|
+
const void *key,
|
|
61
|
+
uint16_t keylen,
|
|
62
|
+
const void* val,
|
|
63
|
+
uint32_t vallen,
|
|
64
|
+
uint64_t cas,
|
|
65
|
+
uint64_t *result_cas)
|
|
66
|
+
{
|
|
67
|
+
(void)cookie;
|
|
68
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
69
|
+
|
|
70
|
+
struct item *item= get_item(key, keylen);
|
|
71
|
+
struct item *nitem;
|
|
72
|
+
|
|
73
|
+
if (item == NULL)
|
|
74
|
+
{
|
|
75
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
76
|
+
}
|
|
77
|
+
else if (cas != 0 && cas != item->cas)
|
|
78
|
+
{
|
|
79
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
80
|
+
}
|
|
81
|
+
else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
|
|
82
|
+
item->flags, item->exp)) == NULL)
|
|
83
|
+
{
|
|
84
|
+
release_item(item);
|
|
85
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
86
|
+
}
|
|
87
|
+
else
|
|
88
|
+
{
|
|
89
|
+
memcpy(nitem->data, item->data, item->size);
|
|
90
|
+
memcpy(((char*)(nitem->data)) + item->size, val, vallen);
|
|
91
|
+
release_item(item);
|
|
92
|
+
delete_item(key, keylen);
|
|
93
|
+
put_item(nitem);
|
|
94
|
+
*result_cas= nitem->cas;
|
|
95
|
+
release_item(nitem);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return rval;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static protocol_binary_response_status decrement_handler(const void *cookie,
|
|
102
|
+
const void *key,
|
|
103
|
+
uint16_t keylen,
|
|
104
|
+
uint64_t delta,
|
|
105
|
+
uint64_t initial,
|
|
106
|
+
uint32_t expiration,
|
|
107
|
+
uint64_t *result,
|
|
108
|
+
uint64_t *result_cas) {
|
|
109
|
+
(void)cookie;
|
|
110
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
111
|
+
uint64_t val= initial;
|
|
112
|
+
struct item *item= get_item(key, keylen);
|
|
113
|
+
|
|
114
|
+
if (item != NULL)
|
|
115
|
+
{
|
|
116
|
+
if (delta > *(uint64_t*)item->data)
|
|
117
|
+
val= 0;
|
|
118
|
+
else
|
|
119
|
+
val= *(uint64_t*)item->data - delta;
|
|
120
|
+
|
|
121
|
+
expiration= (uint32_t)item->exp;
|
|
122
|
+
release_item(item);
|
|
123
|
+
delete_item(key, keylen);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration);
|
|
127
|
+
if (item == 0)
|
|
128
|
+
{
|
|
129
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
{
|
|
133
|
+
memcpy(item->data, &val, sizeof(val));
|
|
134
|
+
put_item(item);
|
|
135
|
+
*result= val;
|
|
136
|
+
*result_cas= item->cas;
|
|
137
|
+
release_item(item);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return rval;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static protocol_binary_response_status delete_handler(const void *cookie,
|
|
144
|
+
const void *key,
|
|
145
|
+
uint16_t keylen,
|
|
146
|
+
uint64_t cas) {
|
|
147
|
+
(void)cookie;
|
|
148
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
149
|
+
|
|
150
|
+
if (cas != 0)
|
|
151
|
+
{
|
|
152
|
+
struct item *item= get_item(key, keylen);
|
|
153
|
+
if (item != NULL)
|
|
154
|
+
{
|
|
155
|
+
if (item->cas != cas)
|
|
156
|
+
{
|
|
157
|
+
release_item(item);
|
|
158
|
+
return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
159
|
+
}
|
|
160
|
+
release_item(item);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!delete_item(key, keylen))
|
|
165
|
+
{
|
|
166
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return rval;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
static protocol_binary_response_status flush_handler(const void *cookie,
|
|
174
|
+
uint32_t when) {
|
|
175
|
+
|
|
176
|
+
(void)cookie;
|
|
177
|
+
flush(when);
|
|
178
|
+
return PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static protocol_binary_response_status get_handler(const void *cookie,
|
|
182
|
+
const void *key,
|
|
183
|
+
uint16_t keylen,
|
|
184
|
+
memcached_binary_protocol_get_response_handler response_handler) {
|
|
185
|
+
struct item *item= get_item(key, keylen);
|
|
186
|
+
|
|
187
|
+
if (item == NULL)
|
|
188
|
+
{
|
|
189
|
+
return PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
protocol_binary_response_status rc;
|
|
193
|
+
rc= response_handler(cookie, key, (uint16_t)keylen,
|
|
194
|
+
item->data, (uint32_t)item->size, item->flags,
|
|
195
|
+
item->cas);
|
|
196
|
+
release_item(item);
|
|
197
|
+
return rc;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static protocol_binary_response_status increment_handler(const void *cookie,
|
|
201
|
+
const void *key,
|
|
202
|
+
uint16_t keylen,
|
|
203
|
+
uint64_t delta,
|
|
204
|
+
uint64_t initial,
|
|
205
|
+
uint32_t expiration,
|
|
206
|
+
uint64_t *result,
|
|
207
|
+
uint64_t *result_cas) {
|
|
208
|
+
(void)cookie;
|
|
209
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
210
|
+
uint64_t val= initial;
|
|
211
|
+
struct item *item= get_item(key, keylen);
|
|
212
|
+
|
|
213
|
+
if (item != NULL)
|
|
214
|
+
{
|
|
215
|
+
val= (*(uint64_t*)item->data) + delta;
|
|
216
|
+
expiration= (uint32_t)item->exp;
|
|
217
|
+
release_item(item);
|
|
218
|
+
delete_item(key, keylen);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration);
|
|
222
|
+
if (item == NULL)
|
|
223
|
+
{
|
|
224
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
225
|
+
}
|
|
226
|
+
else
|
|
227
|
+
{
|
|
228
|
+
char buffer[1024] = {0};
|
|
229
|
+
memcpy(buffer, key, keylen);
|
|
230
|
+
memcpy(item->data, &val, sizeof(val));
|
|
231
|
+
put_item(item);
|
|
232
|
+
*result= val;
|
|
233
|
+
*result_cas= item->cas;
|
|
234
|
+
release_item(item);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return rval;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static protocol_binary_response_status noop_handler(const void *cookie) {
|
|
241
|
+
(void)cookie;
|
|
242
|
+
return PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static protocol_binary_response_status prepend_handler(const void *cookie,
|
|
246
|
+
const void *key,
|
|
247
|
+
uint16_t keylen,
|
|
248
|
+
const void* val,
|
|
249
|
+
uint32_t vallen,
|
|
250
|
+
uint64_t cas,
|
|
251
|
+
uint64_t *result_cas) {
|
|
252
|
+
(void)cookie;
|
|
253
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
254
|
+
|
|
255
|
+
struct item *item= get_item(key, keylen);
|
|
256
|
+
struct item *nitem= NULL;
|
|
257
|
+
|
|
258
|
+
if (item == NULL)
|
|
259
|
+
{
|
|
260
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
261
|
+
}
|
|
262
|
+
else if (cas != 0 && cas != item->cas)
|
|
263
|
+
{
|
|
264
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
265
|
+
}
|
|
266
|
+
else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
|
|
267
|
+
item->flags, item->exp)) == NULL)
|
|
268
|
+
{
|
|
269
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
270
|
+
}
|
|
271
|
+
else
|
|
272
|
+
{
|
|
273
|
+
memcpy(nitem->data, val, vallen);
|
|
274
|
+
memcpy(((char*)(nitem->data)) + vallen, item->data, item->size);
|
|
275
|
+
release_item(item);
|
|
276
|
+
item= NULL;
|
|
277
|
+
delete_item(key, keylen);
|
|
278
|
+
put_item(nitem);
|
|
279
|
+
*result_cas= nitem->cas;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (item)
|
|
283
|
+
release_item(item);
|
|
284
|
+
|
|
285
|
+
if (nitem)
|
|
286
|
+
release_item(nitem);
|
|
287
|
+
|
|
288
|
+
return rval;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static protocol_binary_response_status quit_handler(const void *cookie) {
|
|
292
|
+
(void)cookie;
|
|
293
|
+
return PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
static protocol_binary_response_status replace_handler(const void *cookie,
|
|
297
|
+
const void *key,
|
|
298
|
+
uint16_t keylen,
|
|
299
|
+
const void* data,
|
|
300
|
+
uint32_t datalen,
|
|
301
|
+
uint32_t flags,
|
|
302
|
+
uint32_t exptime,
|
|
303
|
+
uint64_t cas,
|
|
304
|
+
uint64_t *result_cas) {
|
|
305
|
+
(void)cookie;
|
|
306
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
307
|
+
struct item* item= get_item(key, keylen);
|
|
308
|
+
|
|
309
|
+
if (item == NULL)
|
|
310
|
+
{
|
|
311
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
312
|
+
}
|
|
313
|
+
else if (cas == 0 || cas == item->cas)
|
|
314
|
+
{
|
|
315
|
+
release_item(item);
|
|
316
|
+
delete_item(key, keylen);
|
|
317
|
+
item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
|
|
318
|
+
if (item == 0)
|
|
319
|
+
{
|
|
320
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
321
|
+
}
|
|
322
|
+
else
|
|
323
|
+
{
|
|
324
|
+
put_item(item);
|
|
325
|
+
*result_cas= item->cas;
|
|
326
|
+
release_item(item);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else
|
|
330
|
+
{
|
|
331
|
+
rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
332
|
+
release_item(item);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return rval;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
static protocol_binary_response_status set_handler(const void *cookie,
|
|
339
|
+
const void *key,
|
|
340
|
+
uint16_t keylen,
|
|
341
|
+
const void* data,
|
|
342
|
+
uint32_t datalen,
|
|
343
|
+
uint32_t flags,
|
|
344
|
+
uint32_t exptime,
|
|
345
|
+
uint64_t cas,
|
|
346
|
+
uint64_t *result_cas) {
|
|
347
|
+
(void)cookie;
|
|
348
|
+
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
349
|
+
|
|
350
|
+
if (cas != 0)
|
|
351
|
+
{
|
|
352
|
+
struct item* item= get_item(key, keylen);
|
|
353
|
+
if (item != NULL && cas != item->cas)
|
|
354
|
+
{
|
|
355
|
+
/* Invalid CAS value */
|
|
356
|
+
release_item(item);
|
|
357
|
+
return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
delete_item(key, keylen);
|
|
362
|
+
struct item* item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
|
|
363
|
+
if (item == 0)
|
|
364
|
+
{
|
|
365
|
+
rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
|
|
366
|
+
}
|
|
367
|
+
else
|
|
368
|
+
{
|
|
369
|
+
put_item(item);
|
|
370
|
+
*result_cas= item->cas;
|
|
371
|
+
release_item(item);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return rval;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
static protocol_binary_response_status stat_handler(const void *cookie,
|
|
378
|
+
const void *key,
|
|
379
|
+
uint16_t keylen,
|
|
380
|
+
memcached_binary_protocol_stat_response_handler response_handler) {
|
|
381
|
+
(void)key;
|
|
382
|
+
(void)keylen;
|
|
383
|
+
/* Just return an empty packet */
|
|
384
|
+
return response_handler(cookie, NULL, 0, NULL, 0);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
static protocol_binary_response_status version_handler(const void *cookie,
|
|
388
|
+
memcached_binary_protocol_version_response_handler response_handler) {
|
|
389
|
+
const char *version= "0.1.1";
|
|
390
|
+
return response_handler(cookie, version, (uint32_t)strlen(version));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
memcached_binary_protocol_callback_st interface_v1_impl= {
|
|
394
|
+
.interface_version= MEMCACHED_PROTOCOL_HANDLER_V1,
|
|
395
|
+
.interface.v1= {
|
|
396
|
+
.add= add_handler,
|
|
397
|
+
.append= append_handler,
|
|
398
|
+
.decrement= decrement_handler,
|
|
399
|
+
.delete= delete_handler,
|
|
400
|
+
.flush= flush_handler,
|
|
401
|
+
.get= get_handler,
|
|
402
|
+
.increment= increment_handler,
|
|
403
|
+
.noop= noop_handler,
|
|
404
|
+
.prepend= prepend_handler,
|
|
405
|
+
.quit= quit_handler,
|
|
406
|
+
.replace= replace_handler,
|
|
407
|
+
.set= set_handler,
|
|
408
|
+
.stat= stat_handler,
|
|
409
|
+
.version= version_handler
|
|
410
|
+
}
|
|
411
|
+
};
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
2
|
+
/**
|
|
3
|
+
* What is a library without an example to show you how to use the library?
|
|
4
|
+
* This example use both interfaces to implement a small memcached server.
|
|
5
|
+
* Please note that this is an exemple on how to use the library, not
|
|
6
|
+
* an implementation of a scalable memcached server. If you look closely
|
|
7
|
+
* at the example it isn't even multithreaded ;-)
|
|
8
|
+
*
|
|
9
|
+
* With that in mind, let me give you some pointers into the source:
|
|
10
|
+
* storage.c/h - Implements the item store for this server and not really
|
|
11
|
+
* interesting for this example.
|
|
12
|
+
* interface_v0.c - Shows an implementation of the memcached server by using
|
|
13
|
+
* the "raw" access to the packets as they arrive
|
|
14
|
+
* interface_v1.c - Shows an implementation of the memcached server by using
|
|
15
|
+
* the more "logical" interface.
|
|
16
|
+
* memcached_light.c - This file sets up all of the sockets and run the main
|
|
17
|
+
* message loop.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
* config.h is included so that I can use the ntohll/htonll on platforms that
|
|
21
|
+
* doesn't have that (this is a private function inside libmemcached, so you
|
|
22
|
+
* cannot use it directly from libmemcached without special modifications to
|
|
23
|
+
* the library)
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#include "config.h"
|
|
27
|
+
#include <assert.h>
|
|
28
|
+
#include <sys/types.h>
|
|
29
|
+
#include <stdio.h>
|
|
30
|
+
#include <unistd.h>
|
|
31
|
+
#include <fcntl.h>
|
|
32
|
+
#include <errno.h>
|
|
33
|
+
#include <stdlib.h>
|
|
34
|
+
#include <string.h>
|
|
35
|
+
#include <event.h>
|
|
36
|
+
|
|
37
|
+
#include <libmemcached/protocol_handler.h>
|
|
38
|
+
#include <libmemcached/byteorder.h>
|
|
39
|
+
#include "storage.h"
|
|
40
|
+
#include "memcached_light.h"
|
|
41
|
+
|
|
42
|
+
extern memcached_binary_protocol_callback_st interface_v0_impl;
|
|
43
|
+
extern memcached_binary_protocol_callback_st interface_v1_impl;
|
|
44
|
+
|
|
45
|
+
static memcached_socket_t server_sockets[1024];
|
|
46
|
+
static int num_server_sockets= 0;
|
|
47
|
+
|
|
48
|
+
struct connection
|
|
49
|
+
{
|
|
50
|
+
void *userdata;
|
|
51
|
+
struct event event;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/* The default maximum number of connections... (change with -c) */
|
|
55
|
+
static int maxconns = 1024;
|
|
56
|
+
|
|
57
|
+
static struct connection *socket_userdata_map;
|
|
58
|
+
static bool verbose= false;
|
|
59
|
+
static struct event_base *event_base;
|
|
60
|
+
|
|
61
|
+
struct options_st {
|
|
62
|
+
char *pid_file;
|
|
63
|
+
bool has_port;
|
|
64
|
+
in_port_t port;
|
|
65
|
+
} global_options;
|
|
66
|
+
|
|
67
|
+
typedef struct options_st options_st;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Callback for driving a client connection
|
|
71
|
+
* @param fd the socket for the client socket
|
|
72
|
+
* @param which identifying the event that occurred (not used)
|
|
73
|
+
* @param arg the connection structure for the client
|
|
74
|
+
*/
|
|
75
|
+
static void drive_client(memcached_socket_t fd, short which, void *arg)
|
|
76
|
+
{
|
|
77
|
+
(void)which;
|
|
78
|
+
struct connection *client= arg;
|
|
79
|
+
struct memcached_protocol_client_st* c= client->userdata;
|
|
80
|
+
assert(c != NULL);
|
|
81
|
+
|
|
82
|
+
memcached_protocol_event_t events= memcached_protocol_client_work(c);
|
|
83
|
+
if (events & MEMCACHED_PROTOCOL_ERROR_EVENT)
|
|
84
|
+
{
|
|
85
|
+
memcached_protocol_client_destroy(c);
|
|
86
|
+
closesocket(fd);
|
|
87
|
+
} else {
|
|
88
|
+
short flags = 0;
|
|
89
|
+
if (events & MEMCACHED_PROTOCOL_WRITE_EVENT)
|
|
90
|
+
{
|
|
91
|
+
flags= EV_WRITE;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (events & MEMCACHED_PROTOCOL_READ_EVENT)
|
|
95
|
+
{
|
|
96
|
+
flags|= EV_READ;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
event_set(&client->event, (intptr_t)fd, flags, drive_client, client);
|
|
100
|
+
event_base_set(event_base, &client->event);
|
|
101
|
+
|
|
102
|
+
if (event_add(&client->event, 0) == -1)
|
|
103
|
+
{
|
|
104
|
+
(void)fprintf(stderr, "Failed to add event for %d\n", fd);
|
|
105
|
+
memcached_protocol_client_destroy(c);
|
|
106
|
+
closesocket(fd);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Callback for accepting new connections
|
|
113
|
+
* @param fd the socket for the server socket
|
|
114
|
+
* @param which identifying the event that occurred (not used)
|
|
115
|
+
* @param arg the connection structure for the server
|
|
116
|
+
*/
|
|
117
|
+
static void accept_handler(memcached_socket_t fd, short which, void *arg)
|
|
118
|
+
{
|
|
119
|
+
(void)which;
|
|
120
|
+
struct connection *server= arg;
|
|
121
|
+
/* accept new client */
|
|
122
|
+
struct sockaddr_storage addr;
|
|
123
|
+
socklen_t addrlen= sizeof(addr);
|
|
124
|
+
memcached_socket_t sock= accept(fd, (struct sockaddr *)&addr, &addrlen);
|
|
125
|
+
|
|
126
|
+
if (sock == INVALID_SOCKET)
|
|
127
|
+
{
|
|
128
|
+
perror("Failed to accept client");
|
|
129
|
+
return ;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#ifndef WIN32
|
|
133
|
+
if (sock >= maxconns)
|
|
134
|
+
{
|
|
135
|
+
(void)fprintf(stderr, "Client outside socket range (specified with -c)\n");
|
|
136
|
+
closesocket(sock);
|
|
137
|
+
return ;
|
|
138
|
+
}
|
|
139
|
+
#endif
|
|
140
|
+
|
|
141
|
+
struct memcached_protocol_client_st* c;
|
|
142
|
+
c= memcached_protocol_create_client(server->userdata, sock);
|
|
143
|
+
if (c == NULL)
|
|
144
|
+
{
|
|
145
|
+
(void)fprintf(stderr, "Failed to create client\n");
|
|
146
|
+
closesocket(sock);
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
{
|
|
150
|
+
struct connection *client = &socket_userdata_map[sock];
|
|
151
|
+
client->userdata= c;
|
|
152
|
+
|
|
153
|
+
event_set(&client->event, (intptr_t)sock, EV_READ, drive_client, client);
|
|
154
|
+
event_base_set(event_base, &client->event);
|
|
155
|
+
if (event_add(&client->event, 0) == -1)
|
|
156
|
+
{
|
|
157
|
+
(void)fprintf(stderr, "Failed to add event for %d\n", sock);
|
|
158
|
+
memcached_protocol_client_destroy(c);
|
|
159
|
+
closesocket(sock);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create a socket and bind it to a specific port number
|
|
166
|
+
* @param port the port number to bind to
|
|
167
|
+
*/
|
|
168
|
+
static int server_socket(const char *port)
|
|
169
|
+
{
|
|
170
|
+
struct addrinfo *ai;
|
|
171
|
+
struct addrinfo hints= { .ai_flags= AI_PASSIVE,
|
|
172
|
+
.ai_family= AF_UNSPEC,
|
|
173
|
+
.ai_socktype= SOCK_STREAM };
|
|
174
|
+
|
|
175
|
+
int error= getaddrinfo("127.0.0.1", port, &hints, &ai);
|
|
176
|
+
if (error != 0)
|
|
177
|
+
{
|
|
178
|
+
if (error != EAI_SYSTEM)
|
|
179
|
+
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error));
|
|
180
|
+
else
|
|
181
|
+
perror("getaddrinfo()");
|
|
182
|
+
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
struct linger ling= {0, 0};
|
|
187
|
+
|
|
188
|
+
for (struct addrinfo *next= ai; next; next= next->ai_next)
|
|
189
|
+
{
|
|
190
|
+
memcached_socket_t sock= socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
|
191
|
+
if (sock == INVALID_SOCKET)
|
|
192
|
+
{
|
|
193
|
+
perror("Failed to create socket");
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
int flags;
|
|
198
|
+
#ifdef WIN32
|
|
199
|
+
u_long arg = 1;
|
|
200
|
+
if (ioctlsocket(sock, FIONBIO, &arg) == SOCKET_ERROR)
|
|
201
|
+
{
|
|
202
|
+
perror("Failed to set nonblocking io");
|
|
203
|
+
closesocket(sock);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
#else
|
|
207
|
+
flags= fcntl(sock, F_GETFL, 0);
|
|
208
|
+
if (flags == -1)
|
|
209
|
+
{
|
|
210
|
+
perror("Failed to get socket flags");
|
|
211
|
+
closesocket(sock);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if ((flags & O_NONBLOCK) != O_NONBLOCK)
|
|
216
|
+
{
|
|
217
|
+
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
|
|
218
|
+
{
|
|
219
|
+
perror("Failed to set socket to nonblocking mode");
|
|
220
|
+
closesocket(sock);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
#endif
|
|
225
|
+
|
|
226
|
+
flags= 1;
|
|
227
|
+
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)) != 0)
|
|
228
|
+
perror("Failed to set SO_REUSEADDR");
|
|
229
|
+
|
|
230
|
+
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)) != 0)
|
|
231
|
+
perror("Failed to set SO_KEEPALIVE");
|
|
232
|
+
|
|
233
|
+
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)) != 0)
|
|
234
|
+
perror("Failed to set SO_LINGER");
|
|
235
|
+
|
|
236
|
+
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)) != 0)
|
|
237
|
+
perror("Failed to set TCP_NODELAY");
|
|
238
|
+
|
|
239
|
+
if (bind(sock, next->ai_addr, next->ai_addrlen) == SOCKET_ERROR)
|
|
240
|
+
{
|
|
241
|
+
if (get_socket_errno() != EADDRINUSE)
|
|
242
|
+
{
|
|
243
|
+
perror("bind()");
|
|
244
|
+
freeaddrinfo(ai);
|
|
245
|
+
}
|
|
246
|
+
closesocket(sock);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (listen(sock, 1024) == SOCKET_ERROR)
|
|
251
|
+
{
|
|
252
|
+
perror("listen()");
|
|
253
|
+
closesocket(sock);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
server_sockets[num_server_sockets++]= sock;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
freeaddrinfo(ai);
|
|
261
|
+
|
|
262
|
+
return (num_server_sockets > 0) ? 0 : 1;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Convert a command code to a textual string
|
|
267
|
+
* @param cmd the comcode to convert
|
|
268
|
+
* @return a textual string with the command or NULL for unknown commands
|
|
269
|
+
*/
|
|
270
|
+
static const char* comcode2str(uint8_t cmd)
|
|
271
|
+
{
|
|
272
|
+
static const char * const text[] = {
|
|
273
|
+
"GET", "SET", "ADD", "REPLACE", "DELETE",
|
|
274
|
+
"INCREMENT", "DECREMENT", "QUIT", "FLUSH",
|
|
275
|
+
"GETQ", "NOOP", "VERSION", "GETK", "GETKQ",
|
|
276
|
+
"APPEND", "PREPEND", "STAT", "SETQ", "ADDQ",
|
|
277
|
+
"REPLACEQ", "DELETEQ", "INCREMENTQ", "DECREMENTQ",
|
|
278
|
+
"QUITQ", "FLUSHQ", "APPENDQ", "PREPENDQ"
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
if (cmd <= PROTOCOL_BINARY_CMD_PREPENDQ)
|
|
282
|
+
return text[cmd];
|
|
283
|
+
|
|
284
|
+
return NULL;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Print out the command we are about to execute
|
|
289
|
+
*/
|
|
290
|
+
static void pre_execute(const void *cookie,
|
|
291
|
+
protocol_binary_request_header *header)
|
|
292
|
+
{
|
|
293
|
+
if (verbose)
|
|
294
|
+
{
|
|
295
|
+
const char *cmd= comcode2str(header->request.opcode);
|
|
296
|
+
if (cmd != NULL)
|
|
297
|
+
fprintf(stderr, "pre_execute from %p: %s\n", cookie, cmd);
|
|
298
|
+
else
|
|
299
|
+
fprintf(stderr, "pre_execute from %p: 0x%02x\n", cookie, header->request.opcode);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Print out the command we just executed
|
|
305
|
+
*/
|
|
306
|
+
static void post_execute(const void *cookie,
|
|
307
|
+
protocol_binary_request_header *header)
|
|
308
|
+
{
|
|
309
|
+
if (verbose)
|
|
310
|
+
{
|
|
311
|
+
const char *cmd= comcode2str(header->request.opcode);
|
|
312
|
+
if (cmd != NULL)
|
|
313
|
+
fprintf(stderr, "post_execute from %p: %s\n", cookie, cmd);
|
|
314
|
+
else
|
|
315
|
+
fprintf(stderr, "post_execute from %p: 0x%02x\n", cookie, header->request.opcode);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Callback handler for all unknown commands.
|
|
321
|
+
* Send an unknown command back to the client
|
|
322
|
+
*/
|
|
323
|
+
static protocol_binary_response_status unknown(const void *cookie,
|
|
324
|
+
protocol_binary_request_header *header,
|
|
325
|
+
memcached_binary_protocol_raw_response_handler response_handler)
|
|
326
|
+
{
|
|
327
|
+
protocol_binary_response_no_extras response= {
|
|
328
|
+
.message= {
|
|
329
|
+
.header.response= {
|
|
330
|
+
.magic= PROTOCOL_BINARY_RES,
|
|
331
|
+
.opcode= header->request.opcode,
|
|
332
|
+
.status= htons(PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND),
|
|
333
|
+
.opaque= header->request.opaque
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
return response_handler(cookie, header, (void*)&response);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Program entry point. Bind to the specified port(s) and serve clients
|
|
343
|
+
*
|
|
344
|
+
* @param argc number of items in the argument vector
|
|
345
|
+
* @param argv argument vector
|
|
346
|
+
* @return EXIT_SUCCESS on success, 1 otherwise
|
|
347
|
+
*/
|
|
348
|
+
int main(int argc, char **argv)
|
|
349
|
+
{
|
|
350
|
+
int cmd;
|
|
351
|
+
memcached_binary_protocol_callback_st *interface= &interface_v0_impl;
|
|
352
|
+
|
|
353
|
+
memset(&global_options, 0, sizeof(global_options));
|
|
354
|
+
|
|
355
|
+
event_base= event_init();
|
|
356
|
+
if (event_base == NULL)
|
|
357
|
+
{
|
|
358
|
+
fprintf(stderr, "Failed to create an instance of libevent\n");
|
|
359
|
+
return EXIT_FAILURE;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/*
|
|
363
|
+
* We need to initialize the handlers manually due to a bug in the
|
|
364
|
+
* warnings generated by struct initialization in gcc (all the way up to 4.4)
|
|
365
|
+
*/
|
|
366
|
+
initialize_interface_v0_handler();
|
|
367
|
+
|
|
368
|
+
while ((cmd= getopt(argc, argv, "v1p:P:?hc:")) != EOF)
|
|
369
|
+
{
|
|
370
|
+
switch (cmd) {
|
|
371
|
+
case '1':
|
|
372
|
+
interface= &interface_v1_impl;
|
|
373
|
+
break;
|
|
374
|
+
case 'P':
|
|
375
|
+
global_options.pid_file= strdup(optarg);
|
|
376
|
+
break;
|
|
377
|
+
case 'p':
|
|
378
|
+
global_options.has_port= true;
|
|
379
|
+
(void)server_socket(optarg);
|
|
380
|
+
break;
|
|
381
|
+
case 'v':
|
|
382
|
+
verbose= true;
|
|
383
|
+
break;
|
|
384
|
+
case 'c':
|
|
385
|
+
maxconns= atoi(optarg);
|
|
386
|
+
break;
|
|
387
|
+
case 'h': /* FALLTHROUGH */
|
|
388
|
+
case '?': /* FALLTHROUGH */
|
|
389
|
+
default:
|
|
390
|
+
(void)fprintf(stderr, "Usage: %s [-p port] [-v] [-1] [-c #clients] [-P pidfile]\n",
|
|
391
|
+
argv[0]);
|
|
392
|
+
return EXIT_FAILURE;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (! initialize_storage())
|
|
397
|
+
{
|
|
398
|
+
/* Error message already printed */
|
|
399
|
+
return EXIT_FAILURE;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (! global_options.has_port)
|
|
403
|
+
(void)server_socket("9999");
|
|
404
|
+
|
|
405
|
+
if (global_options.pid_file)
|
|
406
|
+
{
|
|
407
|
+
FILE *pid_file;
|
|
408
|
+
uint32_t pid;
|
|
409
|
+
|
|
410
|
+
pid_file= fopen(global_options.pid_file, "w+");
|
|
411
|
+
|
|
412
|
+
if (pid_file == NULL)
|
|
413
|
+
{
|
|
414
|
+
perror(strerror(get_socket_errno()));
|
|
415
|
+
abort();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
pid= (uint32_t)getpid();
|
|
419
|
+
fprintf(pid_file, "%u\n", pid);
|
|
420
|
+
fclose(pid_file);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (num_server_sockets == 0)
|
|
424
|
+
{
|
|
425
|
+
fprintf(stderr, "I don't have any server sockets\n");
|
|
426
|
+
return EXIT_FAILURE;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/*
|
|
430
|
+
* Create and initialize the handles to the protocol handlers. I want
|
|
431
|
+
* to be able to trace the traffic throught the pre/post handlers, and
|
|
432
|
+
* set up a common handler for unknown messages
|
|
433
|
+
*/
|
|
434
|
+
interface->pre_execute= pre_execute;
|
|
435
|
+
interface->post_execute= post_execute;
|
|
436
|
+
interface->unknown= unknown;
|
|
437
|
+
|
|
438
|
+
struct memcached_protocol_st *protocol_handle;
|
|
439
|
+
if ((protocol_handle= memcached_protocol_create_instance()) == NULL)
|
|
440
|
+
{
|
|
441
|
+
fprintf(stderr, "Failed to allocate protocol handle\n");
|
|
442
|
+
return EXIT_FAILURE;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
socket_userdata_map= calloc((size_t)(maxconns), sizeof(struct connection));
|
|
446
|
+
if (socket_userdata_map == NULL)
|
|
447
|
+
{
|
|
448
|
+
fprintf(stderr, "Failed to allocate room for connections\n");
|
|
449
|
+
return EXIT_FAILURE;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
memcached_binary_protocol_set_callbacks(protocol_handle, interface);
|
|
453
|
+
memcached_binary_protocol_set_pedantic(protocol_handle, true);
|
|
454
|
+
|
|
455
|
+
for (int xx= 0; xx < num_server_sockets; ++xx)
|
|
456
|
+
{
|
|
457
|
+
struct connection *conn= &socket_userdata_map[server_sockets[xx]];
|
|
458
|
+
conn->userdata= protocol_handle;
|
|
459
|
+
event_set(&conn->event, (intptr_t)server_sockets[xx], EV_READ | EV_PERSIST,
|
|
460
|
+
accept_handler, conn);
|
|
461
|
+
event_base_set(event_base, &conn->event);
|
|
462
|
+
if (event_add(&conn->event, 0) == -1)
|
|
463
|
+
{
|
|
464
|
+
fprintf(stderr, "Failed to add event for %d\n", server_sockets[xx]);
|
|
465
|
+
closesocket(server_sockets[xx]);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* Serve all of the clients */
|
|
470
|
+
event_base_loop(event_base, 0);
|
|
471
|
+
|
|
472
|
+
/* NOTREACHED */
|
|
473
|
+
return EXIT_SUCCESS;
|
|
474
|
+
}
|