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,31 @@
|
|
1
|
+
/*
|
2
|
+
* Summary: Internal functions used by the library. Not for public use!
|
3
|
+
* Copy: See Copyright for the status of this software.
|
4
|
+
*
|
5
|
+
* Author: Trond Norbye
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef LIBMEMCACHED_MEMCACHED_INTERNAL_H
|
9
|
+
#define LIBMEMCACHED_MEMCACHED_INTERNAL_H
|
10
|
+
|
11
|
+
#if defined(BUILDING_LIBMEMCACHED)
|
12
|
+
|
13
|
+
#ifdef __cplusplus
|
14
|
+
extern "C" {
|
15
|
+
#endif
|
16
|
+
|
17
|
+
LIBMEMCACHED_LOCAL
|
18
|
+
void libmemcached_free(memcached_st *ptr, void *mem);
|
19
|
+
LIBMEMCACHED_LOCAL
|
20
|
+
void *libmemcached_malloc(memcached_st *ptr, const size_t size);
|
21
|
+
LIBMEMCACHED_LOCAL
|
22
|
+
void *libmemcached_realloc(memcached_st *ptr, void *mem, const size_t size);
|
23
|
+
LIBMEMCACHED_LOCAL
|
24
|
+
void *libmemcached_calloc(memcached_st *ptr, size_t nelem, size_t size);
|
25
|
+
|
26
|
+
#ifdef __cplusplus
|
27
|
+
}
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#endif /* BUILDING_LIBMEMCACHED */
|
31
|
+
#endif /* LIBMEMCACHED_MEMCACHED_INTERNAL_H */
|
@@ -0,0 +1,547 @@
|
|
1
|
+
/*
|
2
|
+
Basic socket buffered IO
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "common.h"
|
6
|
+
#include "memcached_io.h"
|
7
|
+
#include <sys/select.h>
|
8
|
+
#include <poll.h>
|
9
|
+
|
10
|
+
typedef enum {
|
11
|
+
MEM_READ,
|
12
|
+
MEM_WRITE,
|
13
|
+
} memc_read_or_write;
|
14
|
+
|
15
|
+
static ssize_t io_flush(memcached_server_st *ptr, memcached_return *error);
|
16
|
+
static void increment_udp_message_id(memcached_server_st *ptr);
|
17
|
+
|
18
|
+
static memcached_return io_wait(memcached_server_st *ptr,
|
19
|
+
memc_read_or_write read_or_write)
|
20
|
+
{
|
21
|
+
struct pollfd fds[1];
|
22
|
+
short flags= 0;
|
23
|
+
int error;
|
24
|
+
|
25
|
+
if (read_or_write == MEM_WRITE) /* write */
|
26
|
+
flags= POLLOUT;
|
27
|
+
else
|
28
|
+
flags= POLLIN;
|
29
|
+
|
30
|
+
memset(&fds, 0, sizeof(struct pollfd));
|
31
|
+
fds[0].fd= ptr->fd;
|
32
|
+
fds[0].events= flags;
|
33
|
+
|
34
|
+
/*
|
35
|
+
** We are going to block on write, but at least on Solaris we might block
|
36
|
+
** on write if we haven't read anything from our input buffer..
|
37
|
+
** Try to purge the input buffer if we don't do any flow control in the
|
38
|
+
** application layer (just sending a lot of data etc)
|
39
|
+
** The test is moved down in the purge function to avoid duplication of
|
40
|
+
** the test.
|
41
|
+
*/
|
42
|
+
if (read_or_write == MEM_WRITE)
|
43
|
+
{
|
44
|
+
memcached_return rc=memcached_purge(ptr);
|
45
|
+
if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED)
|
46
|
+
return MEMCACHED_FAILURE;
|
47
|
+
}
|
48
|
+
|
49
|
+
error= poll(fds, 1, ptr->root->poll_timeout);
|
50
|
+
|
51
|
+
if (error == 1)
|
52
|
+
return MEMCACHED_SUCCESS;
|
53
|
+
else if (error == 0)
|
54
|
+
{
|
55
|
+
return MEMCACHED_TIMEOUT;
|
56
|
+
}
|
57
|
+
|
58
|
+
/* Imposssible for anything other then -1 */
|
59
|
+
WATCHPOINT_ASSERT(error == -1);
|
60
|
+
memcached_quit_server(ptr, 1);
|
61
|
+
|
62
|
+
return MEMCACHED_FAILURE;
|
63
|
+
|
64
|
+
}
|
65
|
+
|
66
|
+
#ifdef UNUSED
|
67
|
+
void memcached_io_preread(memcached_st *ptr)
|
68
|
+
{
|
69
|
+
unsigned int x;
|
70
|
+
|
71
|
+
return;
|
72
|
+
|
73
|
+
for (x= 0; x < ptr->number_of_hosts; x++)
|
74
|
+
{
|
75
|
+
if (memcached_server_response_count(ptr, x) &&
|
76
|
+
ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER )
|
77
|
+
{
|
78
|
+
size_t data_read;
|
79
|
+
|
80
|
+
data_read= read(ptr->hosts[x].fd,
|
81
|
+
ptr->hosts[x].read_ptr + ptr->hosts[x].read_data_length,
|
82
|
+
MEMCACHED_MAX_BUFFER - ptr->hosts[x].read_data_length);
|
83
|
+
if (data_read == -1)
|
84
|
+
continue;
|
85
|
+
|
86
|
+
ptr->hosts[x].read_buffer_length+= data_read;
|
87
|
+
ptr->hosts[x].read_data_length+= data_read;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
#endif
|
92
|
+
|
93
|
+
memcached_return memcached_io_read(memcached_server_st *ptr,
|
94
|
+
void *buffer, size_t length, ssize_t *nread)
|
95
|
+
{
|
96
|
+
char *buffer_ptr;
|
97
|
+
|
98
|
+
buffer_ptr= buffer;
|
99
|
+
|
100
|
+
while (length)
|
101
|
+
{
|
102
|
+
if (!ptr->read_buffer_length)
|
103
|
+
{
|
104
|
+
ssize_t data_read;
|
105
|
+
|
106
|
+
while (1)
|
107
|
+
{
|
108
|
+
data_read= read(ptr->fd, ptr->read_buffer, MEMCACHED_MAX_BUFFER);
|
109
|
+
if (data_read > 0)
|
110
|
+
break;
|
111
|
+
else if (data_read == -1)
|
112
|
+
{
|
113
|
+
ptr->cached_errno= errno;
|
114
|
+
memcached_return rc= MEMCACHED_UNKNOWN_READ_FAILURE;
|
115
|
+
switch (errno)
|
116
|
+
{
|
117
|
+
case EAGAIN:
|
118
|
+
case EINTR:
|
119
|
+
if ((rc= io_wait(ptr, MEM_READ)) == MEMCACHED_SUCCESS)
|
120
|
+
continue;
|
121
|
+
/* fall through */
|
122
|
+
|
123
|
+
default:
|
124
|
+
{
|
125
|
+
memcached_quit_server(ptr, 1);
|
126
|
+
*nread= -1;
|
127
|
+
return rc;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
/*
|
134
|
+
EOF. Any data received so far is incomplete
|
135
|
+
so discard it. This always reads by byte in case of TCP
|
136
|
+
and protocol enforcement happens at memcached_response()
|
137
|
+
looking for '\n'. We do not care for UDB which requests 8 bytes
|
138
|
+
at once. Generally, this means that connection went away. Since
|
139
|
+
for blocking I/O we do not return 0 and for non-blocking case
|
140
|
+
it will return EGAIN if data is not immediatly available.
|
141
|
+
*/
|
142
|
+
memcached_quit_server(ptr, 1);
|
143
|
+
*nread= -1;
|
144
|
+
return MEMCACHED_UNKNOWN_READ_FAILURE;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
ptr->io_bytes_sent = 0;
|
149
|
+
ptr->read_data_length= (size_t) data_read;
|
150
|
+
ptr->read_buffer_length= (size_t) data_read;
|
151
|
+
ptr->read_ptr= ptr->read_buffer;
|
152
|
+
}
|
153
|
+
|
154
|
+
if (length > 1)
|
155
|
+
{
|
156
|
+
size_t difference;
|
157
|
+
|
158
|
+
difference= (length > ptr->read_buffer_length) ? ptr->read_buffer_length : length;
|
159
|
+
|
160
|
+
memcpy(buffer_ptr, ptr->read_ptr, difference);
|
161
|
+
length -= difference;
|
162
|
+
ptr->read_ptr+= difference;
|
163
|
+
ptr->read_buffer_length-= difference;
|
164
|
+
buffer_ptr+= difference;
|
165
|
+
}
|
166
|
+
else
|
167
|
+
{
|
168
|
+
*buffer_ptr= *ptr->read_ptr;
|
169
|
+
ptr->read_ptr++;
|
170
|
+
ptr->read_buffer_length--;
|
171
|
+
buffer_ptr++;
|
172
|
+
break;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
ptr->server_failure_counter= 0;
|
177
|
+
*nread = (ssize_t)(buffer_ptr - (char*)buffer);
|
178
|
+
return MEMCACHED_SUCCESS;
|
179
|
+
}
|
180
|
+
|
181
|
+
ssize_t memcached_io_write(memcached_server_st *ptr,
|
182
|
+
const void *buffer, size_t length, char with_flush)
|
183
|
+
{
|
184
|
+
size_t original_length;
|
185
|
+
const char* buffer_ptr;
|
186
|
+
|
187
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
188
|
+
|
189
|
+
original_length= length;
|
190
|
+
buffer_ptr= buffer;
|
191
|
+
|
192
|
+
while (length)
|
193
|
+
{
|
194
|
+
char *write_ptr;
|
195
|
+
size_t should_write;
|
196
|
+
size_t buffer_end;
|
197
|
+
|
198
|
+
if (ptr->type == MEMCACHED_CONNECTION_UDP)
|
199
|
+
{
|
200
|
+
//UDP does not support partial writes
|
201
|
+
buffer_end= MAX_UDP_DATAGRAM_LENGTH;
|
202
|
+
should_write= length;
|
203
|
+
if (ptr->write_buffer_offset + should_write > buffer_end)
|
204
|
+
return -1;
|
205
|
+
}
|
206
|
+
else
|
207
|
+
{
|
208
|
+
buffer_end= MEMCACHED_MAX_BUFFER;
|
209
|
+
should_write= buffer_end - ptr->write_buffer_offset;
|
210
|
+
should_write= (should_write < length) ? should_write : length;
|
211
|
+
}
|
212
|
+
|
213
|
+
write_ptr= ptr->write_buffer + ptr->write_buffer_offset;
|
214
|
+
memcpy(write_ptr, buffer_ptr, should_write);
|
215
|
+
ptr->write_buffer_offset+= should_write;
|
216
|
+
buffer_ptr+= should_write;
|
217
|
+
length-= should_write;
|
218
|
+
|
219
|
+
if (ptr->write_buffer_offset == buffer_end && ptr->type != MEMCACHED_CONNECTION_UDP)
|
220
|
+
{
|
221
|
+
memcached_return rc;
|
222
|
+
ssize_t sent_length;
|
223
|
+
|
224
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
225
|
+
sent_length= io_flush(ptr, &rc);
|
226
|
+
if (sent_length == -1)
|
227
|
+
return -1;
|
228
|
+
|
229
|
+
/* If io_flush calls memcached_purge, sent_length may be 0 */
|
230
|
+
unlikely (sent_length != 0)
|
231
|
+
{
|
232
|
+
WATCHPOINT_ASSERT(sent_length == (ssize_t)buffer_end);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
if (with_flush)
|
238
|
+
{
|
239
|
+
memcached_return rc;
|
240
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
241
|
+
if (io_flush(ptr, &rc) == -1)
|
242
|
+
return -1;
|
243
|
+
}
|
244
|
+
|
245
|
+
return (ssize_t) original_length;
|
246
|
+
}
|
247
|
+
|
248
|
+
memcached_return memcached_io_close(memcached_server_st *ptr)
|
249
|
+
{
|
250
|
+
int r;
|
251
|
+
|
252
|
+
if (ptr->fd == -1)
|
253
|
+
return MEMCACHED_SUCCESS;
|
254
|
+
|
255
|
+
/* in case of death shutdown to avoid blocking at close() */
|
256
|
+
if (1)
|
257
|
+
{
|
258
|
+
r= shutdown(ptr->fd, SHUT_RDWR);
|
259
|
+
|
260
|
+
#ifdef DEBUG
|
261
|
+
if (r && errno != ENOTCONN)
|
262
|
+
{
|
263
|
+
WATCHPOINT_NUMBER(ptr->fd);
|
264
|
+
WATCHPOINT_ERRNO(errno);
|
265
|
+
WATCHPOINT_ASSERT(errno);
|
266
|
+
}
|
267
|
+
#endif
|
268
|
+
}
|
269
|
+
|
270
|
+
r= close(ptr->fd);
|
271
|
+
#ifdef DEBUG
|
272
|
+
if (r != 0)
|
273
|
+
WATCHPOINT_ERRNO(errno);
|
274
|
+
#endif
|
275
|
+
|
276
|
+
return MEMCACHED_SUCCESS;
|
277
|
+
}
|
278
|
+
|
279
|
+
memcached_server_st *memcached_io_get_readable_server(memcached_st *memc)
|
280
|
+
{
|
281
|
+
#define MAX_SERVERS_TO_POLL 100
|
282
|
+
struct pollfd fds[MAX_SERVERS_TO_POLL];
|
283
|
+
unsigned int host_index= 0;
|
284
|
+
|
285
|
+
for (unsigned int x= 0;
|
286
|
+
x< memc->number_of_hosts && host_index < MAX_SERVERS_TO_POLL;
|
287
|
+
++x)
|
288
|
+
{
|
289
|
+
if (memc->hosts[x].read_buffer_length > 0) /* I have data in the buffer */
|
290
|
+
return &memc->hosts[x];
|
291
|
+
|
292
|
+
if (memcached_server_response_count(&memc->hosts[x]) > 0)
|
293
|
+
{
|
294
|
+
fds[host_index].events = POLLIN;
|
295
|
+
fds[host_index].revents = 0;
|
296
|
+
fds[host_index].fd = memc->hosts[x].fd;
|
297
|
+
++host_index;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
if (host_index < 2)
|
302
|
+
{
|
303
|
+
/* We have 0 or 1 server with pending events.. */
|
304
|
+
for (unsigned int x= 0; x< memc->number_of_hosts; ++x)
|
305
|
+
if (memcached_server_response_count(&memc->hosts[x]) > 0)
|
306
|
+
return &memc->hosts[x];
|
307
|
+
|
308
|
+
return NULL;
|
309
|
+
}
|
310
|
+
|
311
|
+
int err= poll(fds, host_index, memc->poll_timeout);
|
312
|
+
switch (err) {
|
313
|
+
case -1:
|
314
|
+
memc->cached_errno = errno;
|
315
|
+
/* FALLTHROUGH */
|
316
|
+
case 0:
|
317
|
+
break;
|
318
|
+
default:
|
319
|
+
for (unsigned int x= 0; x < host_index; ++x)
|
320
|
+
if (fds[x].revents & POLLIN)
|
321
|
+
for (unsigned int y= 0; y < memc->number_of_hosts; ++y)
|
322
|
+
if (memc->hosts[y].fd == fds[x].fd)
|
323
|
+
return &memc->hosts[y];
|
324
|
+
}
|
325
|
+
|
326
|
+
return NULL;
|
327
|
+
}
|
328
|
+
|
329
|
+
static ssize_t io_flush(memcached_server_st *ptr,
|
330
|
+
memcached_return *error)
|
331
|
+
{
|
332
|
+
/*
|
333
|
+
** We might want to purge the input buffer if we haven't consumed
|
334
|
+
** any output yet... The test for the limits is the purge is inline
|
335
|
+
** in the purge function to avoid duplicating the logic..
|
336
|
+
*/
|
337
|
+
{
|
338
|
+
memcached_return rc;
|
339
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
340
|
+
rc= memcached_purge(ptr);
|
341
|
+
|
342
|
+
if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED)
|
343
|
+
return -1;
|
344
|
+
}
|
345
|
+
ssize_t sent_length;
|
346
|
+
size_t return_length;
|
347
|
+
char *local_write_ptr= ptr->write_buffer;
|
348
|
+
size_t write_length= ptr->write_buffer_offset;
|
349
|
+
|
350
|
+
*error= MEMCACHED_SUCCESS;
|
351
|
+
|
352
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
353
|
+
|
354
|
+
// UDP Sanity check, make sure that we are not sending somthing too big
|
355
|
+
if (ptr->type == MEMCACHED_CONNECTION_UDP && write_length > MAX_UDP_DATAGRAM_LENGTH)
|
356
|
+
return -1;
|
357
|
+
|
358
|
+
if (ptr->write_buffer_offset == 0 || (ptr->type == MEMCACHED_CONNECTION_UDP
|
359
|
+
&& ptr->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH))
|
360
|
+
return 0;
|
361
|
+
|
362
|
+
/* Looking for memory overflows */
|
363
|
+
#if defined(DEBUG)
|
364
|
+
if (write_length == MEMCACHED_MAX_BUFFER)
|
365
|
+
WATCHPOINT_ASSERT(ptr->write_buffer == local_write_ptr);
|
366
|
+
WATCHPOINT_ASSERT((ptr->write_buffer + MEMCACHED_MAX_BUFFER) >= (local_write_ptr + write_length));
|
367
|
+
#endif
|
368
|
+
|
369
|
+
return_length= 0;
|
370
|
+
while (write_length)
|
371
|
+
{
|
372
|
+
WATCHPOINT_ASSERT(ptr->fd != -1);
|
373
|
+
WATCHPOINT_ASSERT(write_length > 0);
|
374
|
+
sent_length= 0;
|
375
|
+
if (ptr->type == MEMCACHED_CONNECTION_UDP)
|
376
|
+
increment_udp_message_id(ptr);
|
377
|
+
sent_length= write(ptr->fd, local_write_ptr, write_length);
|
378
|
+
|
379
|
+
if (sent_length == -1)
|
380
|
+
{
|
381
|
+
ptr->cached_errno= errno;
|
382
|
+
switch (errno)
|
383
|
+
{
|
384
|
+
case ENOBUFS:
|
385
|
+
continue;
|
386
|
+
case EAGAIN:
|
387
|
+
{
|
388
|
+
memcached_return rc;
|
389
|
+
rc= io_wait(ptr, MEM_WRITE);
|
390
|
+
|
391
|
+
if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_TIMEOUT)
|
392
|
+
continue;
|
393
|
+
|
394
|
+
memcached_quit_server(ptr, 1);
|
395
|
+
return -1;
|
396
|
+
}
|
397
|
+
default:
|
398
|
+
memcached_quit_server(ptr, 1);
|
399
|
+
*error= MEMCACHED_ERRNO;
|
400
|
+
return -1;
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
if (ptr->type == MEMCACHED_CONNECTION_UDP &&
|
405
|
+
(size_t)sent_length != write_length)
|
406
|
+
{
|
407
|
+
memcached_quit_server(ptr, 1);
|
408
|
+
return -1;
|
409
|
+
}
|
410
|
+
|
411
|
+
ptr->io_bytes_sent += (uint32_t) sent_length;
|
412
|
+
|
413
|
+
local_write_ptr+= sent_length;
|
414
|
+
write_length-= (uint32_t) sent_length;
|
415
|
+
return_length+= (uint32_t) sent_length;
|
416
|
+
}
|
417
|
+
|
418
|
+
WATCHPOINT_ASSERT(write_length == 0);
|
419
|
+
// Need to study this assert() WATCHPOINT_ASSERT(return_length ==
|
420
|
+
// ptr->write_buffer_offset);
|
421
|
+
|
422
|
+
// if we are a udp server, the begining of the buffer is reserverd for
|
423
|
+
// the upd frame header
|
424
|
+
if (ptr->type == MEMCACHED_CONNECTION_UDP)
|
425
|
+
ptr->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
|
426
|
+
else
|
427
|
+
ptr->write_buffer_offset= 0;
|
428
|
+
|
429
|
+
return (ssize_t) return_length;
|
430
|
+
}
|
431
|
+
|
432
|
+
/*
|
433
|
+
Eventually we will just kill off the server with the problem.
|
434
|
+
*/
|
435
|
+
void memcached_io_reset(memcached_server_st *ptr)
|
436
|
+
{
|
437
|
+
memcached_quit_server(ptr, 1);
|
438
|
+
}
|
439
|
+
|
440
|
+
/**
|
441
|
+
* Read a given number of bytes from the server and place it into a specific
|
442
|
+
* buffer. Reset the IO channel on this server if an error occurs.
|
443
|
+
*/
|
444
|
+
memcached_return memcached_safe_read(memcached_server_st *ptr,
|
445
|
+
void *dta,
|
446
|
+
size_t size)
|
447
|
+
{
|
448
|
+
size_t offset= 0;
|
449
|
+
char *data= dta;
|
450
|
+
|
451
|
+
while (offset < size)
|
452
|
+
{
|
453
|
+
ssize_t nread;
|
454
|
+
memcached_return rc= memcached_io_read(ptr, data + offset, size - offset,
|
455
|
+
&nread);
|
456
|
+
if (rc != MEMCACHED_SUCCESS)
|
457
|
+
return rc;
|
458
|
+
|
459
|
+
offset+= (size_t) nread;
|
460
|
+
}
|
461
|
+
|
462
|
+
return MEMCACHED_SUCCESS;
|
463
|
+
}
|
464
|
+
|
465
|
+
memcached_return memcached_io_readline(memcached_server_st *ptr,
|
466
|
+
char *buffer_ptr,
|
467
|
+
size_t size)
|
468
|
+
{
|
469
|
+
bool line_complete= false;
|
470
|
+
size_t total_nr= 0;
|
471
|
+
|
472
|
+
while (!line_complete)
|
473
|
+
{
|
474
|
+
if (ptr->read_buffer_length == 0)
|
475
|
+
{
|
476
|
+
/*
|
477
|
+
* We don't have any data in the buffer, so let's fill the read
|
478
|
+
* buffer. Call the standard read function to avoid duplicating
|
479
|
+
* the logic.
|
480
|
+
*/
|
481
|
+
ssize_t nread;
|
482
|
+
memcached_return rc= memcached_io_read(ptr, buffer_ptr, 1, &nread);
|
483
|
+
if (rc != MEMCACHED_SUCCESS)
|
484
|
+
return rc;
|
485
|
+
|
486
|
+
if (*buffer_ptr == '\n')
|
487
|
+
line_complete= true;
|
488
|
+
|
489
|
+
++buffer_ptr;
|
490
|
+
++total_nr;
|
491
|
+
}
|
492
|
+
|
493
|
+
/* Now let's look in the buffer and copy as we go! */
|
494
|
+
while (ptr->read_buffer_length && total_nr < size && !line_complete)
|
495
|
+
{
|
496
|
+
*buffer_ptr = *ptr->read_ptr;
|
497
|
+
if (*buffer_ptr == '\n')
|
498
|
+
line_complete = true;
|
499
|
+
--ptr->read_buffer_length;
|
500
|
+
++ptr->read_ptr;
|
501
|
+
++total_nr;
|
502
|
+
++buffer_ptr;
|
503
|
+
}
|
504
|
+
|
505
|
+
if (total_nr == size)
|
506
|
+
return MEMCACHED_PROTOCOL_ERROR;
|
507
|
+
}
|
508
|
+
|
509
|
+
return MEMCACHED_SUCCESS;
|
510
|
+
}
|
511
|
+
|
512
|
+
/*
|
513
|
+
* The udp request id consists of two seperate sections
|
514
|
+
* 1) The thread id
|
515
|
+
* 2) The message number
|
516
|
+
* The thread id should only be set when the memcached_st struct is created
|
517
|
+
* and should not be changed.
|
518
|
+
*
|
519
|
+
* The message num is incremented for each new message we send, this function
|
520
|
+
* extracts the message number from message_id, increments it and then
|
521
|
+
* writes the new value back into the header
|
522
|
+
*/
|
523
|
+
static void increment_udp_message_id(memcached_server_st *ptr)
|
524
|
+
{
|
525
|
+
struct udp_datagram_header_st *header= (struct udp_datagram_header_st *)ptr->write_buffer;
|
526
|
+
uint16_t cur_req= get_udp_datagram_request_id(header);
|
527
|
+
int msg_num= get_msg_num_from_request_id(cur_req);
|
528
|
+
int thread_id= get_thread_id_from_request_id(cur_req);
|
529
|
+
|
530
|
+
if (((++msg_num) & UDP_REQUEST_ID_THREAD_MASK) != 0)
|
531
|
+
msg_num= 0;
|
532
|
+
|
533
|
+
header->request_id= htons((uint16_t) (thread_id | msg_num));
|
534
|
+
}
|
535
|
+
|
536
|
+
memcached_return memcached_io_init_udp_header(memcached_server_st *ptr, uint16_t thread_id)
|
537
|
+
{
|
538
|
+
if (thread_id > UDP_REQUEST_ID_MAX_THREAD_ID)
|
539
|
+
return MEMCACHED_FAILURE;
|
540
|
+
|
541
|
+
struct udp_datagram_header_st *header= (struct udp_datagram_header_st *)ptr->write_buffer;
|
542
|
+
header->request_id= htons((uint16_t) (generate_udp_request_thread_id(thread_id)));
|
543
|
+
header->num_datagrams= htons(1);
|
544
|
+
header->sequence_number= htons(0);
|
545
|
+
|
546
|
+
return MEMCACHED_SUCCESS;
|
547
|
+
}
|