memcached 1.2.6 → 1.2.7
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/CHANGELOG +2 -0
- data/Manifest +206 -12
- data/Rakefile +32 -1
- data/ext/extconf.rb +10 -35
- data/ext/libmemcached-0.32/AUTHORS +7 -0
- data/ext/libmemcached-0.32/COPYING +32 -0
- data/ext/libmemcached-0.32/ChangeLog +303 -0
- data/ext/libmemcached-0.32/INSTALL +302 -0
- data/ext/libmemcached-0.32/Makefile.am +36 -0
- data/ext/libmemcached-0.32/Makefile.in +828 -0
- data/ext/libmemcached-0.32/NEWS +1 -0
- data/ext/libmemcached-0.32/README +33 -0
- data/ext/libmemcached-0.32/THANKS +14 -0
- data/ext/libmemcached-0.32/TODO +11 -0
- data/ext/libmemcached-0.32/aclocal.m4 +1852 -0
- data/ext/libmemcached-0.32/clients/Makefile.am +73 -0
- data/ext/libmemcached-0.32/clients/Makefile.in +770 -0
- data/ext/libmemcached-0.32/clients/client_options.h +32 -0
- data/ext/libmemcached-0.32/clients/execute.c +64 -0
- data/ext/libmemcached-0.32/clients/execute.h +5 -0
- data/ext/libmemcached-0.32/clients/generator.c +74 -0
- data/ext/libmemcached-0.32/clients/generator.h +20 -0
- data/ext/libmemcached-0.32/clients/memcat.c +178 -0
- data/ext/libmemcached-0.32/clients/memcp.c +251 -0
- data/ext/libmemcached-0.32/clients/memdump.c +170 -0
- data/ext/libmemcached-0.32/clients/memerror.c +80 -0
- data/ext/libmemcached-0.32/clients/memflush.c +143 -0
- data/ext/libmemcached-0.32/clients/memrm.c +160 -0
- data/ext/libmemcached-0.32/clients/memslap.c +441 -0
- data/ext/libmemcached-0.32/clients/memstat.c +326 -0
- data/ext/libmemcached-0.32/clients/utilities.c +207 -0
- data/ext/libmemcached-0.32/clients/utilities.h +41 -0
- data/ext/libmemcached-0.32/config.h.in +252 -0
- data/ext/libmemcached-0.32/config/compile +143 -0
- data/ext/libmemcached-0.32/config/config.guess +1561 -0
- data/ext/libmemcached-0.32/config/config.rpath +666 -0
- data/ext/libmemcached-0.32/config/config.sub +1686 -0
- data/ext/libmemcached-0.32/config/depcomp +630 -0
- data/ext/libmemcached-0.32/config/install-sh +520 -0
- data/ext/libmemcached-0.32/config/ltmain.sh +8406 -0
- data/ext/libmemcached-0.32/config/missing +376 -0
- data/ext/libmemcached-0.32/configure +23048 -0
- data/ext/libmemcached-0.32/configure.ac +122 -0
- data/ext/libmemcached-0.32/docs/Makefile.am +415 -0
- data/ext/libmemcached-0.32/docs/Makefile.in +918 -0
- data/ext/libmemcached-0.32/docs/libmemcached.pod +123 -0
- data/ext/libmemcached-0.32/docs/libmemcached_examples.pod +115 -0
- data/ext/libmemcached-0.32/docs/libmemcachedutil.pod +40 -0
- data/ext/libmemcached-0.32/docs/memcached_analyze.pod +52 -0
- data/ext/libmemcached-0.32/docs/memcached_auto.pod +97 -0
- data/ext/libmemcached-0.32/docs/memcached_behavior.pod +224 -0
- data/ext/libmemcached-0.32/docs/memcached_callback.pod +123 -0
- data/ext/libmemcached-0.32/docs/memcached_create.pod +61 -0
- data/ext/libmemcached-0.32/docs/memcached_delete.pod +54 -0
- data/ext/libmemcached-0.32/docs/memcached_dump.pod +53 -0
- data/ext/libmemcached-0.32/docs/memcached_flush.pod +46 -0
- data/ext/libmemcached-0.32/docs/memcached_flush_buffers.pod +42 -0
- data/ext/libmemcached-0.32/docs/memcached_generate_hash_value.pod +57 -0
- data/ext/libmemcached-0.32/docs/memcached_get.pod +161 -0
- data/ext/libmemcached-0.32/docs/memcached_memory_allocators.pod +73 -0
- data/ext/libmemcached-0.32/docs/memcached_pool.pod +77 -0
- data/ext/libmemcached-0.32/docs/memcached_quit.pod +47 -0
- data/ext/libmemcached-0.32/docs/memcached_sasl.pod +63 -0
- data/ext/libmemcached-0.32/docs/memcached_server_st.pod +75 -0
- data/ext/libmemcached-0.32/docs/memcached_servers.pod +102 -0
- data/ext/libmemcached-0.32/docs/memcached_set.pod +187 -0
- data/ext/libmemcached-0.32/docs/memcached_stats.pod +82 -0
- data/ext/libmemcached-0.32/docs/memcached_strerror.pod +46 -0
- data/ext/libmemcached-0.32/docs/memcached_user_data.pod +49 -0
- data/ext/libmemcached-0.32/docs/memcached_verbosity.pod +41 -0
- data/ext/libmemcached-0.32/docs/memcached_version.pod +56 -0
- data/ext/libmemcached-0.32/docs/memcat.pod +37 -0
- data/ext/libmemcached-0.32/docs/memcp.pod +40 -0
- data/ext/libmemcached-0.32/docs/memdump.pod +31 -0
- data/ext/libmemcached-0.32/docs/memerror.pod +30 -0
- data/ext/libmemcached-0.32/docs/memflush.pod +35 -0
- data/ext/libmemcached-0.32/docs/memrm.pod +34 -0
- data/ext/libmemcached-0.32/docs/memslap.pod +33 -0
- data/ext/libmemcached-0.32/docs/memstat.pod +35 -0
- data/ext/libmemcached-0.32/libmemcached/Makefile.am +107 -0
- data/ext/libmemcached-0.32/libmemcached/Makefile.in +1050 -0
- data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
- data/ext/libmemcached-0.32/libmemcached/common.h +183 -0
- data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
- data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
- data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +28 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +78 -0
- data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.c +152 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.h +302 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
- data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
- data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +366 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +285 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +361 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +145 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_do.c +34 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +22 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_get.c +495 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_io.c +547 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_io.h +59 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_response.c +528 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +454 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
- data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
- data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
- data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
- data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +602 -0
- data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
- data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
- data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
- data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
- data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
- data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
- data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
- data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
- data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
- data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
- data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
- data/ext/libmemcached-0.32/m4/libtool.m4 +7360 -0
- data/ext/libmemcached-0.32/m4/ltoptions.m4 +368 -0
- data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
- data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
- data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +92 -0
- data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
- data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
- data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
- data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
- data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
- data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
- data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
- data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
- data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
- data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
- data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
- data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
- data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
- data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
- data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
- data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
- data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
- data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
- data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
- data/ext/libmemcached-0.32/support/Makefile.am +4 -0
- data/ext/libmemcached-0.32/support/Makefile.in +485 -0
- data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
- data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
- data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
- data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
- data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
- data/ext/libmemcached-0.32/tests/Makefile.am +105 -0
- data/ext/libmemcached-0.32/tests/Makefile.in +748 -0
- data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
- data/ext/libmemcached-0.32/tests/function.c +4781 -0
- data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
- data/ext/libmemcached-0.32/tests/output.cmp +7 -0
- data/ext/libmemcached-0.32/tests/output.res +7 -0
- data/ext/libmemcached-0.32/tests/output2.res +46 -0
- data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
- data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
- data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
- data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
- data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
- data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
- data/ext/libmemcached-0.32/tests/server.c +118 -0
- data/ext/libmemcached-0.32/tests/server.h +25 -0
- data/ext/libmemcached-0.32/tests/start.c +16 -0
- data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
- data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
- data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
- data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
- data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
- data/ext/libmemcached-0.32/tests/test.c +137 -0
- data/ext/libmemcached-0.32/tests/test.h +46 -0
- data/ext/libmemcached-0.32/tests/udp.c +76 -0
- data/memcached.gemspec +4 -4
- data/test/unit/memcached_test.rb +30 -0
- metadata +213 -16
- data/ext/libmemcached-0.32.tar.gz +0 -0
- data/ext/libmemcached-1.patch +0 -270
- data/ext/libmemcached-10.patch +0 -12
- data/ext/libmemcached-2.patch +0 -116
- data/ext/libmemcached-3.patch +0 -8
- data/ext/libmemcached-4.patch +0 -40
- data/ext/libmemcached-5.patch +0 -832
- data/ext/libmemcached-6.patch +0 -20
- data/ext/libmemcached-7.patch +0 -2989
- data/ext/libmemcached-8.patch +0 -137
- data/ext/libmemcached-9.patch +0 -13
- data/ext/sasl.patch +0 -29283
@@ -0,0 +1,59 @@
|
|
1
|
+
/*
|
2
|
+
* Summary: Server IO, Not public!
|
3
|
+
*
|
4
|
+
* Copy: See Copyright for the status of this software.
|
5
|
+
*
|
6
|
+
* Author: Brian Aker
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef LIBMEMCACHED_MEMCACHED_IO_H
|
10
|
+
#define LIBMEMCACHED_MEMCACHED_IO_H
|
11
|
+
|
12
|
+
#if defined(BUILDING_LIBMEMCACHED)
|
13
|
+
|
14
|
+
#include "libmemcached/memcached.h"
|
15
|
+
|
16
|
+
#define MAX_UDP_DATAGRAM_LENGTH 1400
|
17
|
+
#define UDP_DATAGRAM_HEADER_LENGTH 8
|
18
|
+
#define UDP_REQUEST_ID_MSG_SIG_DIGITS 10
|
19
|
+
#define UDP_REQUEST_ID_THREAD_MASK 0xFFFF << UDP_REQUEST_ID_MSG_SIG_DIGITS
|
20
|
+
#define get_udp_datagram_request_id(A) ntohs((A)->request_id)
|
21
|
+
#define get_udp_datagram_seq_num(A) ntohs((A)->sequence_number)
|
22
|
+
#define get_udp_datagram_num_datagrams(A) ntohs((A)->num_datagrams)
|
23
|
+
#define get_msg_num_from_request_id(A) ( (A) & (~(UDP_REQUEST_ID_THREAD_MASK)) )
|
24
|
+
#define get_thread_id_from_request_id(A) ( (A) & (UDP_REQUEST_ID_THREAD_MASK) ) >> UDP_REQUEST_ID_MSG_SIG_DIGITS
|
25
|
+
#define generate_udp_request_thread_id(A) (A) << UDP_REQUEST_ID_MSG_SIG_DIGITS
|
26
|
+
#define UDP_REQUEST_ID_MAX_THREAD_ID get_thread_id_from_request_id(0xFFFF)
|
27
|
+
|
28
|
+
struct udp_datagram_header_st {
|
29
|
+
uint16_t request_id;
|
30
|
+
uint16_t sequence_number;
|
31
|
+
uint16_t num_datagrams;
|
32
|
+
uint16_t reserved;
|
33
|
+
};
|
34
|
+
|
35
|
+
ssize_t memcached_io_write(memcached_server_st *ptr,
|
36
|
+
const void *buffer, size_t length, char with_flush);
|
37
|
+
void memcached_io_reset(memcached_server_st *ptr);
|
38
|
+
memcached_return memcached_io_read(memcached_server_st *ptr,
|
39
|
+
void *buffer, size_t length, ssize_t *nread);
|
40
|
+
/* Read a line (terminated by '\n') into the buffer */
|
41
|
+
memcached_return memcached_io_readline(memcached_server_st *ptr,
|
42
|
+
char *buffer_ptr,
|
43
|
+
size_t size);
|
44
|
+
memcached_return memcached_io_close(memcached_server_st *ptr);
|
45
|
+
/* Read n bytes of data from the server and store them in dta */
|
46
|
+
memcached_return memcached_safe_read(memcached_server_st *ptr,
|
47
|
+
void *dta,
|
48
|
+
size_t size);
|
49
|
+
/* Read a single response from the server */
|
50
|
+
memcached_return memcached_read_one_response(memcached_server_st *ptr,
|
51
|
+
char *buffer, size_t buffer_length,
|
52
|
+
memcached_result_st *result);
|
53
|
+
memcached_return memcached_io_init_udp_header(memcached_server_st *ptr,
|
54
|
+
uint16_t thread_id);
|
55
|
+
|
56
|
+
memcached_server_st *memcached_io_get_readable_server(memcached_st *memc);
|
57
|
+
|
58
|
+
#endif /* BUILDING_LIBMEMCACHED */
|
59
|
+
#endif /* LIBMEMCACHED_MEMCACHED_IO_H */
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#include "common.h"
|
2
|
+
|
3
|
+
memcached_return memcached_key_test(const char **keys, size_t *key_length,
|
4
|
+
size_t number_of_keys)
|
5
|
+
{
|
6
|
+
uint32_t x;
|
7
|
+
memcached_return rc;
|
8
|
+
|
9
|
+
for (x= 0; x < number_of_keys; x++)
|
10
|
+
{
|
11
|
+
size_t y;
|
12
|
+
|
13
|
+
rc= memcached_validate_key_length(*(key_length + x), false);
|
14
|
+
if (rc != MEMCACHED_SUCCESS)
|
15
|
+
return rc;
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
for (y= 0; y < *(key_length + x); y++)
|
20
|
+
{
|
21
|
+
if ((isgraph(keys[x][y])) == 0)
|
22
|
+
return MEMCACHED_BAD_KEY_PROVIDED;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
return MEMCACHED_SUCCESS;
|
27
|
+
}
|
28
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/*
|
2
|
+
I debated about putting this in the client library since it does an
|
3
|
+
action I don't really believe belongs in the library.
|
4
|
+
|
5
|
+
Frankly its too damn useful not to be here though.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "common.h"
|
9
|
+
|
10
|
+
memcached_server_st *memcached_servers_parse(const char *server_strings)
|
11
|
+
{
|
12
|
+
char *string;
|
13
|
+
uint32_t port;
|
14
|
+
uint32_t weight;
|
15
|
+
const char *begin_ptr;
|
16
|
+
const char *end_ptr;
|
17
|
+
memcached_server_st *servers= NULL;
|
18
|
+
memcached_return rc;
|
19
|
+
|
20
|
+
WATCHPOINT_ASSERT(server_strings);
|
21
|
+
|
22
|
+
end_ptr= server_strings + strlen(server_strings);
|
23
|
+
|
24
|
+
for (begin_ptr= server_strings, string= index(server_strings, ',');
|
25
|
+
begin_ptr != end_ptr;
|
26
|
+
string= index(begin_ptr, ','))
|
27
|
+
{
|
28
|
+
char buffer[HUGE_STRING_LEN];
|
29
|
+
char *ptr, *ptr2;
|
30
|
+
port= 0;
|
31
|
+
weight= 0;
|
32
|
+
|
33
|
+
if (string)
|
34
|
+
{
|
35
|
+
memcpy(buffer, begin_ptr, (size_t) (string - begin_ptr));
|
36
|
+
buffer[(unsigned int)(string - begin_ptr)]= 0;
|
37
|
+
begin_ptr= string+1;
|
38
|
+
}
|
39
|
+
else
|
40
|
+
{
|
41
|
+
size_t length= strlen(begin_ptr);
|
42
|
+
memcpy(buffer, begin_ptr, length);
|
43
|
+
buffer[length]= 0;
|
44
|
+
begin_ptr= end_ptr;
|
45
|
+
}
|
46
|
+
|
47
|
+
ptr= index(buffer, ':');
|
48
|
+
|
49
|
+
if (ptr)
|
50
|
+
{
|
51
|
+
ptr[0]= 0;
|
52
|
+
|
53
|
+
ptr++;
|
54
|
+
|
55
|
+
port= (uint32_t) strtoul(ptr, (char **)NULL, 10);
|
56
|
+
|
57
|
+
ptr2= index(ptr, ' ');
|
58
|
+
if (! ptr2)
|
59
|
+
ptr2= index(ptr, ':');
|
60
|
+
if (ptr2)
|
61
|
+
{
|
62
|
+
ptr2++;
|
63
|
+
weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
servers= memcached_server_list_append_with_weight(servers, buffer, port, weight, &rc);
|
68
|
+
|
69
|
+
if (isspace(*begin_ptr))
|
70
|
+
begin_ptr++;
|
71
|
+
}
|
72
|
+
|
73
|
+
return servers;
|
74
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/*
|
2
|
+
* Summary: Connection pool implementation for libmemcached.
|
3
|
+
*
|
4
|
+
* Copy: See Copyright for the status of this software.
|
5
|
+
*
|
6
|
+
* Author: Trond Norbye
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef MEMCACHED_POOL_H
|
10
|
+
#define MEMCACHED_POOL_H
|
11
|
+
|
12
|
+
#include <libmemcached/memcached.h>
|
13
|
+
|
14
|
+
#ifdef __cplusplus
|
15
|
+
extern "C" {
|
16
|
+
#endif
|
17
|
+
|
18
|
+
struct memcached_pool_st;
|
19
|
+
typedef struct memcached_pool_st memcached_pool_st;
|
20
|
+
|
21
|
+
LIBMEMCACHED_API
|
22
|
+
memcached_pool_st *memcached_pool_create(memcached_st* mmc, uint32_t initial,
|
23
|
+
uint32_t max);
|
24
|
+
LIBMEMCACHED_API
|
25
|
+
memcached_st* memcached_pool_destroy(memcached_pool_st* pool);
|
26
|
+
LIBMEMCACHED_API
|
27
|
+
memcached_st* memcached_pool_pop(memcached_pool_st* pool,
|
28
|
+
bool block,
|
29
|
+
memcached_return* rc);
|
30
|
+
LIBMEMCACHED_API
|
31
|
+
memcached_return memcached_pool_push(memcached_pool_st* pool,
|
32
|
+
memcached_st* mmc);
|
33
|
+
|
34
|
+
#ifdef __cplusplus
|
35
|
+
}
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#endif /* MEMCACHED_POOL_H */
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#include "common.h"
|
2
|
+
#include "memcached_io.h"
|
3
|
+
#include "memcached_constants.h"
|
4
|
+
|
5
|
+
memcached_return memcached_purge(memcached_server_st *ptr)
|
6
|
+
{
|
7
|
+
uint32_t x;
|
8
|
+
memcached_return ret= MEMCACHED_SUCCESS;
|
9
|
+
|
10
|
+
if (ptr->root->purging || /* already purging */
|
11
|
+
(memcached_server_response_count(ptr) < ptr->root->io_msg_watermark &&
|
12
|
+
ptr->io_bytes_sent < ptr->root->io_bytes_watermark) ||
|
13
|
+
(ptr->io_bytes_sent > ptr->root->io_bytes_watermark &&
|
14
|
+
memcached_server_response_count(ptr) < 2))
|
15
|
+
{
|
16
|
+
return MEMCACHED_SUCCESS;
|
17
|
+
}
|
18
|
+
|
19
|
+
/* memcached_io_write and memcached_response may call memcached_purge
|
20
|
+
so we need to be able stop any recursion.. */
|
21
|
+
ptr->root->purging= 1;
|
22
|
+
|
23
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
24
|
+
/* Force a flush of the buffer to ensure that we don't have the n-1 pending
|
25
|
+
requests buffered up.. */
|
26
|
+
if (memcached_io_write(ptr, NULL, 0, 1) == -1)
|
27
|
+
{
|
28
|
+
ptr->root->purging= 0;
|
29
|
+
return MEMCACHED_WRITE_FAILURE;
|
30
|
+
}
|
31
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
32
|
+
|
33
|
+
uint32_t no_msg= memcached_server_response_count(ptr) - 1;
|
34
|
+
if (no_msg > 0)
|
35
|
+
{
|
36
|
+
memcached_result_st result;
|
37
|
+
memcached_result_st *result_ptr;
|
38
|
+
char buffer[SMALL_STRING_LEN];
|
39
|
+
|
40
|
+
/*
|
41
|
+
* We need to increase the timeout, because we might be waiting for
|
42
|
+
* data to be sent from the server (the commands was in the output buffer
|
43
|
+
* and just flushed
|
44
|
+
*/
|
45
|
+
int32_t timeo= ptr->root->poll_timeout;
|
46
|
+
ptr->root->poll_timeout= 2000;
|
47
|
+
|
48
|
+
result_ptr= memcached_result_create(ptr->root, &result);
|
49
|
+
WATCHPOINT_ASSERT(result_ptr);
|
50
|
+
|
51
|
+
for (x= 0; x < no_msg; x++)
|
52
|
+
{
|
53
|
+
memcached_result_reset(result_ptr);
|
54
|
+
memcached_return rc= memcached_read_one_response(ptr, buffer,
|
55
|
+
sizeof (buffer),
|
56
|
+
result_ptr);
|
57
|
+
/*
|
58
|
+
* Purge doesn't care for what kind of command results that is received.
|
59
|
+
* The only kind of errors I care about if is I'm out of sync with the
|
60
|
+
* protocol or have problems reading data from the network..
|
61
|
+
*/
|
62
|
+
if (rc== MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_UNKNOWN_READ_FAILURE)
|
63
|
+
{
|
64
|
+
WATCHPOINT_ERROR(rc);
|
65
|
+
ret = rc;
|
66
|
+
memcached_io_reset(ptr);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
memcached_result_free(result_ptr);
|
71
|
+
ptr->root->poll_timeout= timeo;
|
72
|
+
}
|
73
|
+
ptr->root->purging= 0;
|
74
|
+
|
75
|
+
return ret;
|
76
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#include "common.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
This closes all connections (forces flush of input as well).
|
5
|
+
|
6
|
+
Maybe add a host specific, or key specific version?
|
7
|
+
|
8
|
+
The reason we send "quit" is that in case we have buffered IO, this
|
9
|
+
will force data to be completed.
|
10
|
+
*/
|
11
|
+
|
12
|
+
void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death)
|
13
|
+
{
|
14
|
+
if (ptr->fd != -1)
|
15
|
+
{
|
16
|
+
if (io_death == 0 && ptr->type != MEMCACHED_CONNECTION_UDP)
|
17
|
+
{
|
18
|
+
memcached_return rc;
|
19
|
+
char buffer[MEMCACHED_MAX_BUFFER];
|
20
|
+
|
21
|
+
if (ptr->root->flags & MEM_BINARY_PROTOCOL)
|
22
|
+
{
|
23
|
+
protocol_binary_request_quit request = {.bytes= {0}};
|
24
|
+
request.message.header.request.magic = PROTOCOL_BINARY_REQ;
|
25
|
+
request.message.header.request.opcode = PROTOCOL_BINARY_CMD_QUIT;
|
26
|
+
request.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
27
|
+
rc= memcached_do(ptr, request.bytes, sizeof(request.bytes), 1);
|
28
|
+
}
|
29
|
+
else
|
30
|
+
rc= memcached_do(ptr, "quit\r\n", 6, 1);
|
31
|
+
|
32
|
+
WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED);
|
33
|
+
|
34
|
+
/* read until socket is closed, or there is an error
|
35
|
+
* closing the socket before all data is read
|
36
|
+
* results in server throwing away all data which is
|
37
|
+
* not read
|
38
|
+
*/
|
39
|
+
ssize_t nread;
|
40
|
+
while (memcached_io_read(ptr, buffer, sizeof(buffer)/sizeof(*buffer),
|
41
|
+
&nread) == MEMCACHED_SUCCESS);
|
42
|
+
}
|
43
|
+
memcached_io_close(ptr);
|
44
|
+
|
45
|
+
ptr->fd= -1;
|
46
|
+
ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0);
|
47
|
+
ptr->read_buffer_length= 0;
|
48
|
+
ptr->read_ptr= ptr->read_buffer;
|
49
|
+
memcached_server_response_reset(ptr);
|
50
|
+
}
|
51
|
+
|
52
|
+
if (io_death)
|
53
|
+
{
|
54
|
+
ptr->server_failure_counter++;
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
ptr->server_failure_counter = 0;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
void memcached_quit(memcached_st *ptr)
|
63
|
+
{
|
64
|
+
unsigned int x;
|
65
|
+
|
66
|
+
if (ptr->hosts == NULL ||
|
67
|
+
ptr->number_of_hosts == 0)
|
68
|
+
return;
|
69
|
+
|
70
|
+
if (ptr->hosts && ptr->number_of_hosts)
|
71
|
+
{
|
72
|
+
for (x= 0; x < ptr->number_of_hosts; x++)
|
73
|
+
memcached_quit_server(&ptr->hosts[x], 0);
|
74
|
+
}
|
75
|
+
}
|
@@ -0,0 +1,528 @@
|
|
1
|
+
/*
|
2
|
+
Memcached library
|
3
|
+
|
4
|
+
memcached_response() is used to determine the return result
|
5
|
+
from an issued command.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "common.h"
|
9
|
+
#include "memcached_io.h"
|
10
|
+
|
11
|
+
static memcached_return textual_read_one_response(memcached_server_st *ptr,
|
12
|
+
char *buffer, size_t buffer_length,
|
13
|
+
memcached_result_st *result);
|
14
|
+
static memcached_return binary_read_one_response(memcached_server_st *ptr,
|
15
|
+
char *buffer, size_t buffer_length,
|
16
|
+
memcached_result_st *result);
|
17
|
+
|
18
|
+
memcached_return memcached_read_one_response(memcached_server_st *ptr,
|
19
|
+
char *buffer, size_t buffer_length,
|
20
|
+
memcached_result_st *result)
|
21
|
+
{
|
22
|
+
memcached_server_response_decrement(ptr);
|
23
|
+
|
24
|
+
if (result == NULL)
|
25
|
+
result = &ptr->root->result;
|
26
|
+
|
27
|
+
memcached_return rc;
|
28
|
+
if (ptr->root->flags & MEM_BINARY_PROTOCOL)
|
29
|
+
rc= binary_read_one_response(ptr, buffer, buffer_length, result);
|
30
|
+
else
|
31
|
+
rc= textual_read_one_response(ptr, buffer, buffer_length, result);
|
32
|
+
|
33
|
+
unlikely(rc == MEMCACHED_UNKNOWN_READ_FAILURE ||
|
34
|
+
rc == MEMCACHED_PROTOCOL_ERROR ||
|
35
|
+
rc == MEMCACHED_CLIENT_ERROR ||
|
36
|
+
rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
|
37
|
+
memcached_io_reset(ptr);
|
38
|
+
|
39
|
+
return rc;
|
40
|
+
}
|
41
|
+
|
42
|
+
memcached_return memcached_response(memcached_server_st *ptr,
|
43
|
+
char *buffer, size_t buffer_length,
|
44
|
+
memcached_result_st *result)
|
45
|
+
{
|
46
|
+
/* We may have old commands in the buffer not set, first purge */
|
47
|
+
if (ptr->root->flags & MEM_NO_BLOCK)
|
48
|
+
(void)memcached_io_write(ptr, NULL, 0, 1);
|
49
|
+
|
50
|
+
/*
|
51
|
+
* The previous implementation purged all pending requests and just
|
52
|
+
* returned the last one. Purge all pending messages to ensure backwards
|
53
|
+
* compatibility.
|
54
|
+
*/
|
55
|
+
if ((ptr->root->flags & MEM_BINARY_PROTOCOL) == 0)
|
56
|
+
while (memcached_server_response_count(ptr) > 1)
|
57
|
+
{
|
58
|
+
memcached_return rc= memcached_read_one_response(ptr, buffer, buffer_length, result);
|
59
|
+
|
60
|
+
unlikely (rc != MEMCACHED_END &&
|
61
|
+
rc != MEMCACHED_STORED &&
|
62
|
+
rc != MEMCACHED_SUCCESS &&
|
63
|
+
rc != MEMCACHED_STAT &&
|
64
|
+
rc != MEMCACHED_DELETED &&
|
65
|
+
rc != MEMCACHED_NOTFOUND &&
|
66
|
+
rc != MEMCACHED_NOTSTORED &&
|
67
|
+
rc != MEMCACHED_DATA_EXISTS)
|
68
|
+
return rc;
|
69
|
+
}
|
70
|
+
|
71
|
+
return memcached_read_one_response(ptr, buffer, buffer_length, result);
|
72
|
+
}
|
73
|
+
|
74
|
+
static memcached_return textual_value_fetch(memcached_server_st *ptr,
|
75
|
+
char *buffer,
|
76
|
+
memcached_result_st *result)
|
77
|
+
{
|
78
|
+
memcached_return rc= MEMCACHED_SUCCESS;
|
79
|
+
char *string_ptr;
|
80
|
+
char *end_ptr;
|
81
|
+
char *next_ptr;
|
82
|
+
size_t value_length;
|
83
|
+
size_t to_read;
|
84
|
+
char *value_ptr;
|
85
|
+
|
86
|
+
if (ptr->root->flags & MEM_USE_UDP)
|
87
|
+
return MEMCACHED_NOT_SUPPORTED;
|
88
|
+
|
89
|
+
WATCHPOINT_ASSERT(ptr->root);
|
90
|
+
end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE;
|
91
|
+
|
92
|
+
memcached_result_reset(result);
|
93
|
+
|
94
|
+
string_ptr= buffer;
|
95
|
+
string_ptr+= 6; /* "VALUE " */
|
96
|
+
|
97
|
+
|
98
|
+
/* We load the key */
|
99
|
+
{
|
100
|
+
char *key;
|
101
|
+
size_t prefix_length;
|
102
|
+
|
103
|
+
key= result->key;
|
104
|
+
result->key_length= 0;
|
105
|
+
|
106
|
+
for (prefix_length= ptr->root->prefix_key_length; !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++)
|
107
|
+
{
|
108
|
+
if (prefix_length == 0)
|
109
|
+
{
|
110
|
+
*key= *string_ptr;
|
111
|
+
key++;
|
112
|
+
result->key_length++;
|
113
|
+
}
|
114
|
+
else
|
115
|
+
prefix_length--;
|
116
|
+
}
|
117
|
+
result->key[result->key_length]= 0;
|
118
|
+
}
|
119
|
+
|
120
|
+
if (end_ptr == string_ptr)
|
121
|
+
goto read_error;
|
122
|
+
|
123
|
+
/* Flags fetch move past space */
|
124
|
+
string_ptr++;
|
125
|
+
if (end_ptr == string_ptr)
|
126
|
+
goto read_error;
|
127
|
+
for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
|
128
|
+
result->flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10);
|
129
|
+
|
130
|
+
if (end_ptr == string_ptr)
|
131
|
+
goto read_error;
|
132
|
+
|
133
|
+
/* Length fetch move past space*/
|
134
|
+
string_ptr++;
|
135
|
+
if (end_ptr == string_ptr)
|
136
|
+
goto read_error;
|
137
|
+
|
138
|
+
for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
|
139
|
+
value_length= (size_t)strtoull(next_ptr, &string_ptr, 10);
|
140
|
+
|
141
|
+
if (end_ptr == string_ptr)
|
142
|
+
goto read_error;
|
143
|
+
|
144
|
+
/* Skip spaces */
|
145
|
+
if (*string_ptr == '\r')
|
146
|
+
{
|
147
|
+
/* Skip past the \r\n */
|
148
|
+
string_ptr+= 2;
|
149
|
+
}
|
150
|
+
else
|
151
|
+
{
|
152
|
+
string_ptr++;
|
153
|
+
for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
|
154
|
+
result->cas= strtoull(next_ptr, &string_ptr, 10);
|
155
|
+
}
|
156
|
+
|
157
|
+
if (end_ptr < string_ptr)
|
158
|
+
goto read_error;
|
159
|
+
|
160
|
+
/* We add two bytes so that we can walk the \r\n */
|
161
|
+
rc= memcached_string_check(&result->value, value_length+2);
|
162
|
+
if (rc != MEMCACHED_SUCCESS)
|
163
|
+
{
|
164
|
+
value_length= 0;
|
165
|
+
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
|
166
|
+
}
|
167
|
+
|
168
|
+
value_ptr= memcached_string_value(&result->value);
|
169
|
+
/*
|
170
|
+
We read the \r\n into the string since not doing so is more
|
171
|
+
cycles then the waster of memory to do so.
|
172
|
+
|
173
|
+
We are null terminating through, which will most likely make
|
174
|
+
some people lazy about using the return length.
|
175
|
+
*/
|
176
|
+
to_read= (value_length) + 2;
|
177
|
+
ssize_t read_length= 0;
|
178
|
+
memcached_return rrc= memcached_io_read(ptr, value_ptr, to_read, &read_length);
|
179
|
+
if (rrc != MEMCACHED_SUCCESS)
|
180
|
+
return rrc;
|
181
|
+
|
182
|
+
if (read_length != (ssize_t)(value_length + 2))
|
183
|
+
{
|
184
|
+
goto read_error;
|
185
|
+
}
|
186
|
+
|
187
|
+
/* This next bit blows the API, but this is internal....*/
|
188
|
+
{
|
189
|
+
char *char_ptr;
|
190
|
+
char_ptr= memcached_string_value(&result->value);;
|
191
|
+
char_ptr[value_length]= 0;
|
192
|
+
char_ptr[value_length + 1]= 0;
|
193
|
+
memcached_string_set_length(&result->value, value_length);
|
194
|
+
}
|
195
|
+
|
196
|
+
return MEMCACHED_SUCCESS;
|
197
|
+
|
198
|
+
read_error:
|
199
|
+
memcached_io_reset(ptr);
|
200
|
+
|
201
|
+
return MEMCACHED_PARTIAL_READ;
|
202
|
+
}
|
203
|
+
|
204
|
+
static memcached_return textual_read_one_response(memcached_server_st *ptr,
|
205
|
+
char *buffer, size_t buffer_length,
|
206
|
+
memcached_result_st *result)
|
207
|
+
{
|
208
|
+
memcached_return rc= memcached_io_readline(ptr, buffer, buffer_length);
|
209
|
+
if (rc != MEMCACHED_SUCCESS)
|
210
|
+
return rc;
|
211
|
+
|
212
|
+
switch(buffer[0])
|
213
|
+
{
|
214
|
+
case 'V': /* VALUE || VERSION */
|
215
|
+
if (buffer[1] == 'A') /* VALUE */
|
216
|
+
{
|
217
|
+
/* We add back in one because we will need to search for END */
|
218
|
+
memcached_server_response_increment(ptr);
|
219
|
+
return textual_value_fetch(ptr, buffer, result);
|
220
|
+
}
|
221
|
+
else if (buffer[1] == 'E') /* VERSION */
|
222
|
+
{
|
223
|
+
return MEMCACHED_SUCCESS;
|
224
|
+
}
|
225
|
+
else
|
226
|
+
{
|
227
|
+
WATCHPOINT_STRING(buffer);
|
228
|
+
WATCHPOINT_ASSERT(0);
|
229
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
230
|
+
}
|
231
|
+
case 'O': /* OK */
|
232
|
+
return MEMCACHED_SUCCESS;
|
233
|
+
case 'S': /* STORED STATS SERVER_ERROR */
|
234
|
+
{
|
235
|
+
if (buffer[2] == 'A') /* STORED STATS */
|
236
|
+
{
|
237
|
+
memcached_server_response_increment(ptr);
|
238
|
+
return MEMCACHED_STAT;
|
239
|
+
}
|
240
|
+
else if (buffer[1] == 'E') /* SERVER_ERROR */
|
241
|
+
{
|
242
|
+
memcached_server_error_reset(ptr);
|
243
|
+
|
244
|
+
char *startptr= buffer + 13, *endptr= startptr;
|
245
|
+
while (*endptr != '\r' && *endptr != '\n')
|
246
|
+
endptr++;
|
247
|
+
size_t err_len = (endptr - startptr + 1);
|
248
|
+
|
249
|
+
ptr->cached_server_error = malloc(err_len);
|
250
|
+
if (ptr->cached_server_error == NULL)
|
251
|
+
return MEMCACHED_SERVER_ERROR;
|
252
|
+
|
253
|
+
strncpy(ptr->cached_server_error, startptr, err_len);
|
254
|
+
ptr->cached_server_error[err_len - 1]= 0;
|
255
|
+
return MEMCACHED_SERVER_ERROR;
|
256
|
+
}
|
257
|
+
else if (buffer[1] == 'T')
|
258
|
+
return MEMCACHED_STORED;
|
259
|
+
else
|
260
|
+
{
|
261
|
+
WATCHPOINT_STRING(buffer);
|
262
|
+
WATCHPOINT_ASSERT(0);
|
263
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
264
|
+
}
|
265
|
+
}
|
266
|
+
case 'D': /* DELETED */
|
267
|
+
return MEMCACHED_DELETED;
|
268
|
+
case 'N': /* NOT_FOUND */
|
269
|
+
{
|
270
|
+
if (buffer[4] == 'F')
|
271
|
+
return MEMCACHED_NOTFOUND;
|
272
|
+
else if (buffer[4] == 'S')
|
273
|
+
return MEMCACHED_NOTSTORED;
|
274
|
+
else
|
275
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
276
|
+
}
|
277
|
+
case 'E': /* PROTOCOL ERROR or END */
|
278
|
+
{
|
279
|
+
if (buffer[1] == 'N')
|
280
|
+
return MEMCACHED_END;
|
281
|
+
else if (buffer[1] == 'R')
|
282
|
+
return MEMCACHED_PROTOCOL_ERROR;
|
283
|
+
else if (buffer[1] == 'X')
|
284
|
+
return MEMCACHED_DATA_EXISTS;
|
285
|
+
else
|
286
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
287
|
+
}
|
288
|
+
case 'I': /* CLIENT ERROR */
|
289
|
+
/* We add back in one because we will need to search for END */
|
290
|
+
memcached_server_response_increment(ptr);
|
291
|
+
return MEMCACHED_ITEM;
|
292
|
+
case 'C': /* CLIENT ERROR */
|
293
|
+
return MEMCACHED_CLIENT_ERROR;
|
294
|
+
default:
|
295
|
+
{
|
296
|
+
unsigned long long auto_return_value;
|
297
|
+
|
298
|
+
if (sscanf(buffer, "%llu", &auto_return_value) == 1)
|
299
|
+
return MEMCACHED_SUCCESS;
|
300
|
+
|
301
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
/* NOTREACHED */
|
306
|
+
}
|
307
|
+
|
308
|
+
char *memcached_result_value(memcached_result_st *ptr)
|
309
|
+
{
|
310
|
+
memcached_string_st *sptr= &ptr->value;
|
311
|
+
return memcached_string_value(sptr);
|
312
|
+
}
|
313
|
+
|
314
|
+
size_t memcached_result_length(memcached_result_st *ptr)
|
315
|
+
{
|
316
|
+
memcached_string_st *sptr= &ptr->value;
|
317
|
+
return memcached_string_length(sptr);
|
318
|
+
}
|
319
|
+
|
320
|
+
static memcached_return binary_read_one_response(memcached_server_st *ptr,
|
321
|
+
char *buffer, size_t buffer_length,
|
322
|
+
memcached_result_st *result)
|
323
|
+
{
|
324
|
+
protocol_binary_response_header header;
|
325
|
+
|
326
|
+
unlikely (memcached_safe_read(ptr, &header.bytes,
|
327
|
+
sizeof(header.bytes)) != MEMCACHED_SUCCESS)
|
328
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
329
|
+
|
330
|
+
unlikely (header.response.magic != PROTOCOL_BINARY_RES)
|
331
|
+
return MEMCACHED_PROTOCOL_ERROR;
|
332
|
+
|
333
|
+
/*
|
334
|
+
** Convert the header to host local endian!
|
335
|
+
*/
|
336
|
+
header.response.keylen= ntohs(header.response.keylen);
|
337
|
+
header.response.status= ntohs(header.response.status);
|
338
|
+
header.response.bodylen= ntohl(header.response.bodylen);
|
339
|
+
header.response.cas= ntohll(header.response.cas);
|
340
|
+
uint32_t bodylen= header.response.bodylen;
|
341
|
+
|
342
|
+
if (header.response.status == PROTOCOL_BINARY_RESPONSE_SUCCESS ||
|
343
|
+
header.response.status == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE)
|
344
|
+
{
|
345
|
+
switch (header.response.opcode)
|
346
|
+
{
|
347
|
+
case PROTOCOL_BINARY_CMD_GETK:
|
348
|
+
case PROTOCOL_BINARY_CMD_GETKQ:
|
349
|
+
{
|
350
|
+
uint16_t keylen= header.response.keylen;
|
351
|
+
memcached_result_reset(result);
|
352
|
+
result->cas= header.response.cas;
|
353
|
+
|
354
|
+
if (memcached_safe_read(ptr, &result->flags,
|
355
|
+
sizeof (result->flags)) != MEMCACHED_SUCCESS)
|
356
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
357
|
+
|
358
|
+
result->flags= ntohl(result->flags);
|
359
|
+
bodylen -= header.response.extlen;
|
360
|
+
|
361
|
+
result->key_length= keylen;
|
362
|
+
if (memcached_safe_read(ptr, result->key, keylen) != MEMCACHED_SUCCESS)
|
363
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
364
|
+
|
365
|
+
bodylen -= keylen;
|
366
|
+
if (memcached_string_check(&result->value,
|
367
|
+
bodylen) != MEMCACHED_SUCCESS)
|
368
|
+
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
|
369
|
+
|
370
|
+
char *vptr= memcached_string_value(&result->value);
|
371
|
+
if (memcached_safe_read(ptr, vptr, bodylen) != MEMCACHED_SUCCESS)
|
372
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
373
|
+
|
374
|
+
size_t prefix_length = ptr->root->prefix_key_length;
|
375
|
+
memmove(result->key, (result->key + prefix_length), keylen - prefix_length + 1);
|
376
|
+
result->key_length = keylen - prefix_length;
|
377
|
+
|
378
|
+
memcached_string_set_length(&result->value, bodylen);
|
379
|
+
}
|
380
|
+
break;
|
381
|
+
case PROTOCOL_BINARY_CMD_INCREMENT:
|
382
|
+
case PROTOCOL_BINARY_CMD_DECREMENT:
|
383
|
+
{
|
384
|
+
if (bodylen != sizeof(uint64_t) || buffer_length != sizeof(uint64_t))
|
385
|
+
return MEMCACHED_PROTOCOL_ERROR;
|
386
|
+
|
387
|
+
WATCHPOINT_ASSERT(bodylen == buffer_length);
|
388
|
+
uint64_t val;
|
389
|
+
if (memcached_safe_read(ptr, &val, sizeof(val)) != MEMCACHED_SUCCESS)
|
390
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
391
|
+
|
392
|
+
val= ntohll(val);
|
393
|
+
memcpy(buffer, &val, sizeof(val));
|
394
|
+
}
|
395
|
+
break;
|
396
|
+
case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
|
397
|
+
case PROTOCOL_BINARY_CMD_VERSION:
|
398
|
+
{
|
399
|
+
memset(buffer, 0, buffer_length);
|
400
|
+
if (bodylen >= buffer_length)
|
401
|
+
/* not enough space in buffer.. should not happen... */
|
402
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
403
|
+
else if (memcached_safe_read(ptr, buffer, bodylen) != MEMCACHED_SUCCESS)
|
404
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
405
|
+
}
|
406
|
+
break;
|
407
|
+
case PROTOCOL_BINARY_CMD_FLUSH:
|
408
|
+
case PROTOCOL_BINARY_CMD_QUIT:
|
409
|
+
case PROTOCOL_BINARY_CMD_SET:
|
410
|
+
case PROTOCOL_BINARY_CMD_ADD:
|
411
|
+
case PROTOCOL_BINARY_CMD_REPLACE:
|
412
|
+
case PROTOCOL_BINARY_CMD_APPEND:
|
413
|
+
case PROTOCOL_BINARY_CMD_PREPEND:
|
414
|
+
case PROTOCOL_BINARY_CMD_DELETE:
|
415
|
+
{
|
416
|
+
WATCHPOINT_ASSERT(bodylen == 0);
|
417
|
+
return MEMCACHED_SUCCESS;
|
418
|
+
}
|
419
|
+
case PROTOCOL_BINARY_CMD_NOOP:
|
420
|
+
{
|
421
|
+
WATCHPOINT_ASSERT(bodylen == 0);
|
422
|
+
return MEMCACHED_END;
|
423
|
+
}
|
424
|
+
case PROTOCOL_BINARY_CMD_STAT:
|
425
|
+
{
|
426
|
+
if (bodylen == 0)
|
427
|
+
return MEMCACHED_END;
|
428
|
+
else if (bodylen + 1 > buffer_length)
|
429
|
+
/* not enough space in buffer.. should not happen... */
|
430
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
431
|
+
else
|
432
|
+
{
|
433
|
+
size_t keylen= header.response.keylen;
|
434
|
+
memset(buffer, 0, buffer_length);
|
435
|
+
if (memcached_safe_read(ptr, buffer, keylen) != MEMCACHED_SUCCESS ||
|
436
|
+
memcached_safe_read(ptr, buffer + keylen + 1,
|
437
|
+
bodylen - keylen) != MEMCACHED_SUCCESS)
|
438
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
439
|
+
}
|
440
|
+
}
|
441
|
+
break;
|
442
|
+
|
443
|
+
case PROTOCOL_BINARY_CMD_SASL_AUTH:
|
444
|
+
case PROTOCOL_BINARY_CMD_SASL_STEP:
|
445
|
+
{
|
446
|
+
memcached_result_reset(result);
|
447
|
+
result->cas= header.response.cas;
|
448
|
+
|
449
|
+
if (memcached_string_check(&result->value,
|
450
|
+
bodylen) != MEMCACHED_SUCCESS)
|
451
|
+
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
|
452
|
+
|
453
|
+
char *vptr= memcached_string_value(&result->value);
|
454
|
+
if (memcached_safe_read(ptr, vptr, bodylen) != MEMCACHED_SUCCESS)
|
455
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
456
|
+
|
457
|
+
memcached_string_set_length(&result->value, bodylen);
|
458
|
+
}
|
459
|
+
break;
|
460
|
+
|
461
|
+
default:
|
462
|
+
{
|
463
|
+
/* Command not implemented yet! */
|
464
|
+
WATCHPOINT_ASSERT(0);
|
465
|
+
return MEMCACHED_PROTOCOL_ERROR;
|
466
|
+
}
|
467
|
+
}
|
468
|
+
}
|
469
|
+
else if (header.response.bodylen)
|
470
|
+
{
|
471
|
+
/* What should I do with the error message??? just discard it for now */
|
472
|
+
char hole[SMALL_STRING_LEN];
|
473
|
+
while (bodylen > 0)
|
474
|
+
{
|
475
|
+
size_t nr= (bodylen > SMALL_STRING_LEN) ? SMALL_STRING_LEN : bodylen;
|
476
|
+
if (memcached_safe_read(ptr, hole, nr) != MEMCACHED_SUCCESS)
|
477
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
478
|
+
bodylen-= (uint32_t) nr;
|
479
|
+
}
|
480
|
+
|
481
|
+
/* This might be an error from one of the quiet commands.. if
|
482
|
+
* so, just throw it away and get the next one. What about creating
|
483
|
+
* a callback to the user with the error information?
|
484
|
+
*/
|
485
|
+
switch (header.response.opcode)
|
486
|
+
{
|
487
|
+
case PROTOCOL_BINARY_CMD_SETQ:
|
488
|
+
case PROTOCOL_BINARY_CMD_ADDQ:
|
489
|
+
case PROTOCOL_BINARY_CMD_REPLACEQ:
|
490
|
+
case PROTOCOL_BINARY_CMD_APPENDQ:
|
491
|
+
case PROTOCOL_BINARY_CMD_PREPENDQ:
|
492
|
+
return binary_read_one_response(ptr, buffer, buffer_length, result);
|
493
|
+
default:
|
494
|
+
break;
|
495
|
+
}
|
496
|
+
}
|
497
|
+
|
498
|
+
memcached_return rc= MEMCACHED_SUCCESS;
|
499
|
+
unlikely(header.response.status != 0)
|
500
|
+
switch (header.response.status)
|
501
|
+
{
|
502
|
+
case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
|
503
|
+
rc= MEMCACHED_NOTFOUND;
|
504
|
+
break;
|
505
|
+
case PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS:
|
506
|
+
rc= MEMCACHED_DATA_EXISTS;
|
507
|
+
break;
|
508
|
+
case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE:
|
509
|
+
rc= MEMCACHED_AUTH_CONTINUE;
|
510
|
+
break;
|
511
|
+
case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR:
|
512
|
+
rc= MEMCACHED_AUTH_FAILURE;
|
513
|
+
break;
|
514
|
+
case PROTOCOL_BINARY_RESPONSE_E2BIG:
|
515
|
+
case PROTOCOL_BINARY_RESPONSE_EINVAL:
|
516
|
+
case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
|
517
|
+
rc= MEMCACHED_NOTSTORED;
|
518
|
+
break;
|
519
|
+
case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
|
520
|
+
case PROTOCOL_BINARY_RESPONSE_ENOMEM:
|
521
|
+
default:
|
522
|
+
/* @todo fix the error mappings */
|
523
|
+
rc= MEMCACHED_PROTOCOL_ERROR;
|
524
|
+
break;
|
525
|
+
}
|
526
|
+
|
527
|
+
return rc;
|
528
|
+
}
|