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.
Files changed (225) hide show
  1. data/CHANGELOG +2 -0
  2. data/Manifest +206 -12
  3. data/Rakefile +32 -1
  4. data/ext/extconf.rb +10 -35
  5. data/ext/libmemcached-0.32/AUTHORS +7 -0
  6. data/ext/libmemcached-0.32/COPYING +32 -0
  7. data/ext/libmemcached-0.32/ChangeLog +303 -0
  8. data/ext/libmemcached-0.32/INSTALL +302 -0
  9. data/ext/libmemcached-0.32/Makefile.am +36 -0
  10. data/ext/libmemcached-0.32/Makefile.in +828 -0
  11. data/ext/libmemcached-0.32/NEWS +1 -0
  12. data/ext/libmemcached-0.32/README +33 -0
  13. data/ext/libmemcached-0.32/THANKS +14 -0
  14. data/ext/libmemcached-0.32/TODO +11 -0
  15. data/ext/libmemcached-0.32/aclocal.m4 +1852 -0
  16. data/ext/libmemcached-0.32/clients/Makefile.am +73 -0
  17. data/ext/libmemcached-0.32/clients/Makefile.in +770 -0
  18. data/ext/libmemcached-0.32/clients/client_options.h +32 -0
  19. data/ext/libmemcached-0.32/clients/execute.c +64 -0
  20. data/ext/libmemcached-0.32/clients/execute.h +5 -0
  21. data/ext/libmemcached-0.32/clients/generator.c +74 -0
  22. data/ext/libmemcached-0.32/clients/generator.h +20 -0
  23. data/ext/libmemcached-0.32/clients/memcat.c +178 -0
  24. data/ext/libmemcached-0.32/clients/memcp.c +251 -0
  25. data/ext/libmemcached-0.32/clients/memdump.c +170 -0
  26. data/ext/libmemcached-0.32/clients/memerror.c +80 -0
  27. data/ext/libmemcached-0.32/clients/memflush.c +143 -0
  28. data/ext/libmemcached-0.32/clients/memrm.c +160 -0
  29. data/ext/libmemcached-0.32/clients/memslap.c +441 -0
  30. data/ext/libmemcached-0.32/clients/memstat.c +326 -0
  31. data/ext/libmemcached-0.32/clients/utilities.c +207 -0
  32. data/ext/libmemcached-0.32/clients/utilities.h +41 -0
  33. data/ext/libmemcached-0.32/config.h.in +252 -0
  34. data/ext/libmemcached-0.32/config/compile +143 -0
  35. data/ext/libmemcached-0.32/config/config.guess +1561 -0
  36. data/ext/libmemcached-0.32/config/config.rpath +666 -0
  37. data/ext/libmemcached-0.32/config/config.sub +1686 -0
  38. data/ext/libmemcached-0.32/config/depcomp +630 -0
  39. data/ext/libmemcached-0.32/config/install-sh +520 -0
  40. data/ext/libmemcached-0.32/config/ltmain.sh +8406 -0
  41. data/ext/libmemcached-0.32/config/missing +376 -0
  42. data/ext/libmemcached-0.32/configure +23048 -0
  43. data/ext/libmemcached-0.32/configure.ac +122 -0
  44. data/ext/libmemcached-0.32/docs/Makefile.am +415 -0
  45. data/ext/libmemcached-0.32/docs/Makefile.in +918 -0
  46. data/ext/libmemcached-0.32/docs/libmemcached.pod +123 -0
  47. data/ext/libmemcached-0.32/docs/libmemcached_examples.pod +115 -0
  48. data/ext/libmemcached-0.32/docs/libmemcachedutil.pod +40 -0
  49. data/ext/libmemcached-0.32/docs/memcached_analyze.pod +52 -0
  50. data/ext/libmemcached-0.32/docs/memcached_auto.pod +97 -0
  51. data/ext/libmemcached-0.32/docs/memcached_behavior.pod +224 -0
  52. data/ext/libmemcached-0.32/docs/memcached_callback.pod +123 -0
  53. data/ext/libmemcached-0.32/docs/memcached_create.pod +61 -0
  54. data/ext/libmemcached-0.32/docs/memcached_delete.pod +54 -0
  55. data/ext/libmemcached-0.32/docs/memcached_dump.pod +53 -0
  56. data/ext/libmemcached-0.32/docs/memcached_flush.pod +46 -0
  57. data/ext/libmemcached-0.32/docs/memcached_flush_buffers.pod +42 -0
  58. data/ext/libmemcached-0.32/docs/memcached_generate_hash_value.pod +57 -0
  59. data/ext/libmemcached-0.32/docs/memcached_get.pod +161 -0
  60. data/ext/libmemcached-0.32/docs/memcached_memory_allocators.pod +73 -0
  61. data/ext/libmemcached-0.32/docs/memcached_pool.pod +77 -0
  62. data/ext/libmemcached-0.32/docs/memcached_quit.pod +47 -0
  63. data/ext/libmemcached-0.32/docs/memcached_sasl.pod +63 -0
  64. data/ext/libmemcached-0.32/docs/memcached_server_st.pod +75 -0
  65. data/ext/libmemcached-0.32/docs/memcached_servers.pod +102 -0
  66. data/ext/libmemcached-0.32/docs/memcached_set.pod +187 -0
  67. data/ext/libmemcached-0.32/docs/memcached_stats.pod +82 -0
  68. data/ext/libmemcached-0.32/docs/memcached_strerror.pod +46 -0
  69. data/ext/libmemcached-0.32/docs/memcached_user_data.pod +49 -0
  70. data/ext/libmemcached-0.32/docs/memcached_verbosity.pod +41 -0
  71. data/ext/libmemcached-0.32/docs/memcached_version.pod +56 -0
  72. data/ext/libmemcached-0.32/docs/memcat.pod +37 -0
  73. data/ext/libmemcached-0.32/docs/memcp.pod +40 -0
  74. data/ext/libmemcached-0.32/docs/memdump.pod +31 -0
  75. data/ext/libmemcached-0.32/docs/memerror.pod +30 -0
  76. data/ext/libmemcached-0.32/docs/memflush.pod +35 -0
  77. data/ext/libmemcached-0.32/docs/memrm.pod +34 -0
  78. data/ext/libmemcached-0.32/docs/memslap.pod +33 -0
  79. data/ext/libmemcached-0.32/docs/memstat.pod +35 -0
  80. data/ext/libmemcached-0.32/libmemcached/Makefile.am +107 -0
  81. data/ext/libmemcached-0.32/libmemcached/Makefile.in +1050 -0
  82. data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
  83. data/ext/libmemcached-0.32/libmemcached/common.h +183 -0
  84. data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
  85. data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
  86. data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
  87. data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
  88. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +28 -0
  89. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +78 -0
  90. data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
  91. data/ext/libmemcached-0.32/libmemcached/memcached.c +152 -0
  92. data/ext/libmemcached-0.32/libmemcached/memcached.h +302 -0
  93. data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
  94. data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
  95. data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +366 -0
  96. data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
  97. data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
  98. data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
  99. data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +285 -0
  100. data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
  101. data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
  102. data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +361 -0
  103. data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +145 -0
  104. data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
  105. data/ext/libmemcached-0.32/libmemcached/memcached_do.c +34 -0
  106. data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
  107. data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
  108. data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
  109. data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +22 -0
  110. data/ext/libmemcached-0.32/libmemcached/memcached_get.c +495 -0
  111. data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
  112. data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
  113. data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
  114. data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
  115. data/ext/libmemcached-0.32/libmemcached/memcached_io.c +547 -0
  116. data/ext/libmemcached-0.32/libmemcached/memcached_io.h +59 -0
  117. data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
  118. data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
  119. data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
  120. data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
  121. data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
  122. data/ext/libmemcached-0.32/libmemcached/memcached_response.c +528 -0
  123. data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
  124. data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
  125. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
  126. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
  127. data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
  128. data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
  129. data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +454 -0
  130. data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
  131. data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
  132. data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
  133. data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
  134. data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
  135. data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
  136. data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
  137. data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
  138. data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
  139. data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
  140. data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
  141. data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
  142. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
  143. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +602 -0
  144. data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
  145. data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
  146. data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
  147. data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
  148. data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
  149. data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
  150. data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
  151. data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
  152. data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
  153. data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
  154. data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
  155. data/ext/libmemcached-0.32/m4/libtool.m4 +7360 -0
  156. data/ext/libmemcached-0.32/m4/ltoptions.m4 +368 -0
  157. data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
  158. data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
  159. data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +92 -0
  160. data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
  161. data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
  162. data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
  163. data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
  164. data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
  165. data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
  166. data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
  167. data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
  168. data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
  169. data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
  170. data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
  171. data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
  172. data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
  173. data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
  174. data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
  175. data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
  176. data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
  177. data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
  178. data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
  179. data/ext/libmemcached-0.32/support/Makefile.am +4 -0
  180. data/ext/libmemcached-0.32/support/Makefile.in +485 -0
  181. data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
  182. data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
  183. data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
  184. data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
  185. data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
  186. data/ext/libmemcached-0.32/tests/Makefile.am +105 -0
  187. data/ext/libmemcached-0.32/tests/Makefile.in +748 -0
  188. data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
  189. data/ext/libmemcached-0.32/tests/function.c +4781 -0
  190. data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
  191. data/ext/libmemcached-0.32/tests/output.cmp +7 -0
  192. data/ext/libmemcached-0.32/tests/output.res +7 -0
  193. data/ext/libmemcached-0.32/tests/output2.res +46 -0
  194. data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
  195. data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
  196. data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
  197. data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
  198. data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
  199. data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
  200. data/ext/libmemcached-0.32/tests/server.c +118 -0
  201. data/ext/libmemcached-0.32/tests/server.h +25 -0
  202. data/ext/libmemcached-0.32/tests/start.c +16 -0
  203. data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
  204. data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
  205. data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
  206. data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
  207. data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
  208. data/ext/libmemcached-0.32/tests/test.c +137 -0
  209. data/ext/libmemcached-0.32/tests/test.h +46 -0
  210. data/ext/libmemcached-0.32/tests/udp.c +76 -0
  211. data/memcached.gemspec +4 -4
  212. data/test/unit/memcached_test.rb +30 -0
  213. metadata +213 -16
  214. data/ext/libmemcached-0.32.tar.gz +0 -0
  215. data/ext/libmemcached-1.patch +0 -270
  216. data/ext/libmemcached-10.patch +0 -12
  217. data/ext/libmemcached-2.patch +0 -116
  218. data/ext/libmemcached-3.patch +0 -8
  219. data/ext/libmemcached-4.patch +0 -40
  220. data/ext/libmemcached-5.patch +0 -832
  221. data/ext/libmemcached-6.patch +0 -20
  222. data/ext/libmemcached-7.patch +0 -2989
  223. data/ext/libmemcached-8.patch +0 -137
  224. data/ext/libmemcached-9.patch +0 -13
  225. 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
+ }