libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -1,584 +0,0 @@
1
- /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2014 Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #include "manager.h"
19
- #include "hostlist.h"
20
- #include "iotable.h"
21
- #include "timer-ng.h"
22
- #include "internal.h"
23
-
24
- #define LOGARGS(mgr, lvl) mgr->settings, "lcbio_mgr", LCB_LOG_##lvl, __FILE__, __LINE__
25
-
26
- typedef enum {
27
- CS_PENDING,
28
- CS_IDLE,
29
- CS_LEASED
30
- } cinfo_state;
31
-
32
- typedef enum {
33
- RS_PENDING,
34
- RS_ASSIGNED
35
- } request_state;
36
-
37
- typedef char mgr_KEY[NI_MAXSERV + NI_MAXHOST + 2];
38
-
39
- typedef struct lcbio_MGRHOST {
40
- lcb_clist_t ll_idle; /* idle connections */
41
- lcb_clist_t ll_pending; /* pending cinfo */
42
- lcb_clist_t requests; /* pending requests */
43
- mgr_KEY key; /* host:port */
44
- struct lcbio_MGR *parent;
45
- lcbio_pASYNC async;
46
- unsigned n_total; /* number of total connections */
47
- unsigned refcount;
48
- } mgr_HOST;
49
-
50
- typedef struct mgr_CINFO_st {
51
- lcbio_PROTOCTX base;
52
- lcb_list_t llnode;
53
- mgr_HOST *parent;
54
- lcbio_SOCKET *sock;
55
- struct lcbio_CONNSTART *cs;
56
- lcbio_pTIMER idle_timer;
57
- int state;
58
- } mgr_CINFO;
59
-
60
- typedef struct lcbio_MGRREQ {
61
- lcb_list_t llnode;
62
- lcbio_CONNDONE_cb callback;
63
- void *arg;
64
- mgr_HOST *host;
65
- lcbio_pTIMER timer;
66
- int state;
67
- lcbio_SOCKET *sock;
68
- lcb_error_t err;
69
- } mgr_REQ;
70
-
71
- #define HE_NPEND(he) LCB_CLIST_SIZE(&(he)->ll_pending)
72
- #define HE_NIDLE(he) LCB_CLIST_SIZE(&(he)->ll_idle)
73
- #define HE_NREQS(he) LCB_CLIST_SIZE(&(he)->requests)
74
- #define HE_NLEASED(he) ((he)->n_total - (HE_NIDLE(he) + HE_NPEND(he)))
75
-
76
- static void on_idle_timeout(void *cookie);
77
- static void he_available_notify(void *cookie);
78
- static void he_dump(mgr_HOST *he, FILE *out);
79
- static void he_unref(mgr_HOST *he);
80
- static void mgr_unref(lcbio_MGR *mgr);
81
-
82
- #define he_ref(he) (he)->refcount++
83
- #define mgr_ref(mgr) (mgr)->refcount++
84
-
85
- static const char *get_hehost(mgr_HOST *h) {
86
- if (!h) { return "NOHOST:NOPORT"; }
87
- return h->key;
88
- }
89
-
90
- /** Format string arguments for %p%s:%s */
91
- #define HE_LOGID(h) get_hehost(h), (void*)h
92
- #define HE_LOGFMT "<%s> (HE=%p) "
93
-
94
- static mgr_CINFO *
95
- cinfo_from_sock(lcbio_SOCKET *sock)
96
- {
97
- lcbio_PROTOCTX *ctx = lcbio_protoctx_get(sock, LCBIO_PROTOCTX_POOL);
98
- return (mgr_CINFO *)ctx;
99
- }
100
-
101
- static void
102
- destroy_cinfo(mgr_CINFO *info)
103
- {
104
- info->parent->n_total--;
105
- if (info->state == CS_IDLE) {
106
- lcb_clist_delete(&info->parent->ll_idle, &info->llnode);
107
-
108
- } else if (info->state == CS_PENDING && info->cs) {
109
- lcbio_connect_cancel(info->cs);
110
- }
111
-
112
- if (info->sock) {
113
- lcbio_SOCKET *s = info->sock;
114
- info->sock = NULL;
115
- lcbio_protoctx_delptr(s, &info->base, 0);
116
- lcbio_unref(s);
117
- }
118
- lcbio_timer_destroy(info->idle_timer);
119
- he_unref(info->parent);
120
- free(info);
121
- }
122
-
123
- static void
124
- cinfo_protoctx_dtor(lcbio_PROTOCTX *ctx)
125
- {
126
- mgr_CINFO *info = (void *)ctx;
127
- info->sock = NULL;
128
- destroy_cinfo(info);
129
- }
130
-
131
- lcbio_MGR *
132
- lcbio_mgr_create(lcb_settings *settings, lcbio_TABLE *io)
133
- {
134
- lcbio_MGR *pool = calloc(1, sizeof(*pool));
135
- if (!pool) {
136
- return NULL;
137
- }
138
-
139
- if ((pool->ht = lcb_hashtable_nc_new(32)) == NULL) {
140
- free(pool);
141
- return NULL;
142
- }
143
-
144
- pool->settings = settings;
145
- pool->io = io;
146
- mgr_ref(pool);
147
- return pool;
148
- }
149
-
150
- static void
151
- iterfunc(const void *k, lcb_size_t nk, const void *v, lcb_size_t nv, void *arg)
152
- {
153
- lcb_clist_t *he_list = (lcb_clist_t *)arg;
154
- mgr_HOST *he = (mgr_HOST *)v;
155
- lcb_list_t *cur, *next;
156
-
157
- LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->ll_idle) {
158
- mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
159
- destroy_cinfo(info);
160
- }
161
-
162
- LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->ll_pending) {
163
- mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
164
- destroy_cinfo(info);
165
- }
166
-
167
- memset(&he->ll_idle, 0, sizeof(he->ll_idle));
168
- lcb_clist_append(he_list, (lcb_list_t *)&he->ll_idle);
169
-
170
- (void)k; (void)nk; (void)nv;
171
- }
172
-
173
- static void
174
- he_unref(mgr_HOST *host)
175
- {
176
- if (--host->refcount) {
177
- return;
178
- }
179
-
180
- mgr_unref(host->parent);
181
- free(host);
182
- }
183
-
184
- static void
185
- mgr_unref(lcbio_MGR *mgr)
186
- {
187
- if (--mgr->refcount) {
188
- return;
189
- }
190
- genhash_free(mgr->ht);
191
- free(mgr);
192
- }
193
-
194
- void
195
- lcbio_mgr_destroy(lcbio_MGR *mgr)
196
- {
197
- lcb_clist_t hes;
198
- lcb_list_t *cur, *next;
199
- lcb_clist_init(&hes);
200
-
201
- genhash_iter(mgr->ht, iterfunc, &hes);
202
-
203
- LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t*)&hes) {
204
- mgr_HOST *he = LCB_LIST_ITEM(cur, mgr_HOST, ll_idle);
205
- genhash_delete(mgr->ht, he->key, strlen(he->key));
206
- lcb_clist_delete(&hes, (lcb_list_t *)&he->ll_idle);
207
- lcbio_timer_destroy(he->async);
208
- he->async = NULL;
209
- he_unref(he);
210
- }
211
- mgr_unref(mgr);
212
- }
213
-
214
- static void
215
- invoke_request(mgr_REQ *req)
216
- {
217
- if (req->sock) {
218
- mgr_CINFO *info = cinfo_from_sock(req->sock);
219
- lcb_assert(info->state == CS_IDLE);
220
- info->state = CS_LEASED;
221
- req->state = RS_ASSIGNED;
222
- lcbio_timer_disarm(info->idle_timer);
223
- lcb_log(LOGARGS(info->parent->parent, DEBUG), HE_LOGFMT "Assigning R=%p SOCKET=%p",HE_LOGID(info->parent), (void*)req, (void*)req->sock);
224
- }
225
-
226
- if (req->timer) {
227
- lcbio_timer_destroy(req->timer);
228
- req->timer = NULL;
229
- }
230
-
231
- req->callback(req->sock, req->arg, req->err, 0);
232
- if (req->sock) {
233
- lcbio_unref(req->sock);
234
- }
235
- free(req);
236
- }
237
-
238
- /**
239
- * Called to notify that a connection has become available.
240
- */
241
- static void
242
- connection_available(mgr_HOST *he)
243
- {
244
- while (LCB_CLIST_SIZE(&he->requests) && LCB_CLIST_SIZE(&he->ll_idle)) {
245
- mgr_REQ *req;
246
- mgr_CINFO *info;
247
- lcb_list_t *reqitem, *connitem;
248
-
249
- reqitem = lcb_clist_shift(&he->requests);
250
- connitem = lcb_clist_pop(&he->ll_idle);
251
-
252
- req = LCB_LIST_ITEM(reqitem, mgr_REQ, llnode);
253
- info = LCB_LIST_ITEM(connitem, mgr_CINFO, llnode);
254
- req->sock = info->sock;
255
- req->err = LCB_SUCCESS;
256
- invoke_request(req);
257
- }
258
- }
259
-
260
- /**
261
- * Connection callback invoked from lcbio_connect() when a result is received
262
- */
263
- static void
264
- on_connected(lcbio_SOCKET *sock, void *arg, lcb_error_t err, lcbio_OSERR oserr)
265
- {
266
- mgr_CINFO *info = arg;
267
- mgr_HOST *he = info->parent;
268
- lcb_assert(info->state == CS_PENDING);
269
- info->cs = NULL;
270
-
271
- lcb_log(LOGARGS(he->parent, DEBUG), HE_LOGFMT "Received result for I=%p,C=%p; E=0x%x", HE_LOGID(he), (void*)info, (void*)sock, err);
272
- lcb_clist_delete(&he->ll_pending, &info->llnode);
273
-
274
- if (err != LCB_SUCCESS) {
275
- /** If the connection failed, fail out all remaining requests */
276
- lcb_list_t *cur, *next;
277
- LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->requests) {
278
- mgr_REQ *req = LCB_LIST_ITEM(cur, mgr_REQ, llnode);
279
- lcb_clist_delete(&he->requests, &req->llnode);
280
- req->sock = NULL;
281
- req->err = err;
282
- invoke_request(req);
283
- }
284
-
285
- destroy_cinfo(info);
286
-
287
- } else {
288
- info->state = CS_IDLE;
289
- info->sock = sock;
290
- lcbio_ref(info->sock);
291
- lcbio_protoctx_add(sock, &info->base);
292
-
293
- lcb_clist_append(&he->ll_idle, &info->llnode);
294
- lcbio_timer_rearm(info->idle_timer, he->parent->tmoidle);
295
- connection_available(info->parent);
296
- }
297
-
298
- (void)oserr;
299
- }
300
-
301
- static void
302
- start_new_connection(mgr_HOST *he, uint32_t tmo)
303
- {
304
- lcb_host_t tmphost;
305
- lcb_error_t err;
306
-
307
- mgr_CINFO *info = calloc(1, sizeof(*info));
308
- info->state = CS_PENDING;
309
- info->parent = he;
310
-
311
- info->base.id = LCBIO_PROTOCTX_POOL;
312
- info->base.dtor = cinfo_protoctx_dtor;
313
- info->idle_timer = lcbio_timer_new(he->parent->io, info, on_idle_timeout);
314
-
315
- err = lcb_host_parsez(&tmphost, he->key, 80);
316
- if (err != LCB_SUCCESS) {
317
- lcb_log(LOGARGS(he->parent, ERROR), HE_LOGFMT "Could not parse host! Will supply dummy host", HE_LOGID(he));
318
- strcpy(tmphost.host, "BADHOST");
319
- strcpy(tmphost.port, "BADPORT");
320
- }
321
- lcb_log(LOGARGS(he->parent, DEBUG), HE_LOGFMT "Starting connection on I=%p", HE_LOGID(he), (void*)info);
322
-
323
- info->cs = lcbio_connect(he->parent->io, he->parent->settings, &tmphost,
324
- tmo, on_connected, info);
325
-
326
- lcb_clist_append(&he->ll_pending, &info->llnode);
327
- he->n_total++;
328
- he_ref(he);
329
- }
330
-
331
- static void
332
- on_request_timeout(void *cookie)
333
- {
334
- mgr_REQ *req = cookie;
335
- lcb_clist_delete(&req->host->requests, &req->llnode);
336
- req->err = LCB_ETIMEDOUT;
337
- invoke_request(req);
338
- }
339
-
340
- static void
341
- async_invoke_request(void *cookie)
342
- {
343
-
344
- mgr_REQ *req = cookie;
345
- mgr_CINFO *cinfo = cinfo_from_sock(req->sock);
346
- cinfo->state = CS_IDLE;
347
- invoke_request(req);
348
- }
349
-
350
- mgr_REQ *
351
- lcbio_mgr_get(lcbio_MGR *pool, lcb_host_t *dest, uint32_t timeout,
352
- lcbio_CONNDONE_cb handler, void *arg)
353
- {
354
- mgr_HOST *he;
355
- lcb_list_t *cur;
356
- mgr_REQ *req = calloc(1, sizeof(*req));
357
- mgr_KEY key = { 0 };
358
-
359
- sprintf(key, "%s:%s", dest->host, dest->port);
360
-
361
- req->callback = handler;
362
- req->arg = arg;
363
-
364
- he = genhash_find(pool->ht, key, strlen(key));
365
- if (!he) {
366
- he = calloc(1, sizeof(*he));
367
- he->parent = pool;
368
- he->async = lcbio_timer_new(pool->io, he, he_available_notify);
369
- strcpy(he->key, key);
370
-
371
- lcb_clist_init(&he->ll_idle);
372
- lcb_clist_init(&he->ll_pending);
373
- lcb_clist_init(&he->requests);
374
-
375
- /** Not copied */
376
- genhash_store(pool->ht, he->key, strlen(he->key), he, 0);
377
- he_ref(he);
378
- mgr_ref(pool);
379
- }
380
-
381
- req->host = he;
382
-
383
- GT_POPAGAIN:
384
-
385
- cur = lcb_clist_pop(&he->ll_idle);
386
- if (cur) {
387
- int clstatus;
388
- mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
389
-
390
- clstatus = lcbio_is_netclosed(info->sock, LCB_IO_SOCKCHECK_PEND_IS_ERROR);
391
-
392
- if (clstatus == LCB_IO_SOCKCHECK_STATUS_CLOSED) {
393
- lcb_log(LOGARGS(pool, WARN), HE_LOGFMT "Pooled socket is dead. Continuing to next one", HE_LOGID(he));
394
-
395
- /* Set to CS_LEASED, since it's not inside any of our lists */
396
- info->state = CS_LEASED;
397
- destroy_cinfo(info);
398
- goto GT_POPAGAIN;
399
- }
400
-
401
- lcbio_timer_disarm(info->idle_timer);
402
- req->sock = info->sock;
403
- req->state = RS_ASSIGNED;
404
- req->timer = lcbio_timer_new(pool->io, req, async_invoke_request);
405
- info->state = CS_LEASED;
406
- lcbio_async_signal(req->timer);
407
- lcb_log(LOGARGS(pool, INFO), HE_LOGFMT "Found ready connection in pool. Reusing socket and not creating new connection", HE_LOGID(he));
408
-
409
- } else {
410
- req->state = RS_PENDING;
411
- req->timer = lcbio_timer_new(pool->io, req, on_request_timeout);
412
- lcbio_timer_rearm(req->timer, timeout);
413
-
414
- lcb_clist_append(&he->requests, &req->llnode);
415
- if (HE_NPEND(he) < HE_NREQS(he)) {
416
- lcb_log(LOGARGS(pool, DEBUG), HE_LOGFMT "Creating new connection because none are available in the pool", HE_LOGID(he));
417
- start_new_connection(he, timeout);
418
-
419
- } else {
420
- lcb_log(LOGARGS(pool, DEBUG), HE_LOGFMT "Not creating a new connection. There are still pending ones", HE_LOGID(he));
421
- }
422
- }
423
-
424
- return req;
425
- }
426
-
427
- /**
428
- * Invoked when a new socket is available for allocation within the
429
- * request queue.
430
- */
431
- static void
432
- he_available_notify(void *cookie)
433
- {
434
- connection_available((mgr_HOST *)cookie);
435
- }
436
-
437
- void
438
- lcbio_mgr_cancel(mgr_REQ *req)
439
- {
440
- mgr_HOST *he = req->host;
441
- lcbio_MGR *mgr = he->parent;
442
- if (req->timer) {
443
- lcbio_timer_destroy(req->timer);
444
- req->timer = NULL;
445
- }
446
-
447
- if (req->sock) {
448
- lcb_log(LOGARGS(mgr, DEBUG), HE_LOGFMT "Cancelling request=%p with existing connection", HE_LOGID(he), (void*)req);
449
- lcbio_mgr_put(req->sock);
450
- lcbio_async_signal(he->async);
451
-
452
- } else {
453
- lcb_log(LOGARGS(mgr, DEBUG), HE_LOGFMT "Request=%p has no connection.. yet", HE_LOGID(he), (void*)req);
454
- lcb_clist_delete(&he->requests, &req->llnode);
455
- }
456
- free(req);
457
- }
458
-
459
- static void
460
- on_idle_timeout(void *cookie)
461
- {
462
- mgr_CINFO *info = cookie;
463
-
464
- lcb_log(LOGARGS(info->parent->parent, DEBUG), HE_LOGFMT "Idle connection expired", HE_LOGID(info->parent));
465
-
466
- lcbio_unref(info->sock);
467
- }
468
-
469
- void
470
- lcbio_mgr_put(lcbio_SOCKET *sock)
471
- {
472
- mgr_HOST *he;
473
- lcbio_MGR *mgr;
474
- mgr_CINFO *info = cinfo_from_sock(sock);
475
-
476
- if (!info) {
477
- fprintf(stderr, "Requested put() for non-pooled (or detached) socket=%p\n", (void *)sock);
478
- lcbio_unref(sock);
479
- return;
480
- }
481
-
482
- he = info->parent;
483
- mgr = he->parent;
484
-
485
- if (HE_NIDLE(he) >= mgr->maxidle) {
486
- lcb_log(LOGARGS(mgr, INFO), HE_LOGFMT "Closing idle connection. Too many in quota", HE_LOGID(he));
487
- lcbio_unref(info->sock);
488
- return;
489
- }
490
-
491
- lcb_log(LOGARGS(mgr, INFO), HE_LOGFMT "Placing socket back into the pool. I=%p,C=%p", HE_LOGID(he), (void*)info, (void*)sock);
492
- lcbio_timer_rearm(info->idle_timer, mgr->tmoidle);
493
- lcb_clist_append(&he->ll_idle, &info->llnode);
494
- info->state = CS_IDLE;
495
- }
496
-
497
- void
498
- lcbio_mgr_discard(lcbio_SOCKET *sock)
499
- {
500
- lcbio_unref(sock);
501
- }
502
-
503
- void
504
- lcbio_mgr_detach(lcbio_SOCKET *sock)
505
- {
506
- lcbio_protoctx_delid(sock, LCBIO_PROTOCTX_POOL, 1);
507
- }
508
-
509
-
510
- #define CONN_INDENT " "
511
-
512
- static void
513
- write_he_list(lcb_clist_t *ll, FILE *out)
514
- {
515
- lcb_list_t *llcur;
516
- LCB_LIST_FOR(llcur, (lcb_list_t *)ll) {
517
- mgr_CINFO *info = LCB_LIST_ITEM(llcur, mgr_CINFO, llnode);
518
- fprintf(out, "%sCONN [I=%p,C=%p ",
519
- CONN_INDENT, (void *)info, (void *)&info->sock);
520
-
521
- if (info->sock->io->model == LCB_IOMODEL_EVENT) {
522
- fprintf(out, "SOCKFD=%d", (int)info->sock->u.fd);
523
- } else {
524
- fprintf(out, "SOCKDATA=%p", (void *)info->sock->u.sd);
525
- }
526
- fprintf(out, " STATE=0x%x", info->state);
527
- fprintf(out, "]\n");
528
- }
529
-
530
- }
531
-
532
- static void
533
- he_dump(mgr_HOST *he, FILE *out)
534
- {
535
- lcb_list_t *llcur;
536
- fprintf(out, "HOST=%s", he->key);
537
- fprintf(out, "Requests=%d, Idle=%d, Pending=%d, Leased=%d\n",
538
- (int)HE_NREQS(he), (int)HE_NIDLE(he), (int)HE_NPEND(he), (int)HE_NLEASED(he));
539
-
540
- fprintf(out, CONN_INDENT "Idle Connections:\n");
541
- write_he_list(&he->ll_idle, out);
542
- fprintf(out, CONN_INDENT "Pending Connections: \n");
543
- write_he_list(&he->ll_pending, out);
544
- fprintf(out, CONN_INDENT "Pending Requests:\n");
545
-
546
- LCB_LIST_FOR(llcur, (lcb_list_t *)&he->requests) {
547
- mgr_REQ *req = LCB_LIST_ITEM(llcur, mgr_REQ, llnode);
548
- union {
549
- lcbio_CONNDONE_cb cb;
550
- void *ptr;
551
- } u_cb;
552
-
553
- u_cb.cb = req->callback;
554
-
555
- fprintf(out, "%sREQ [R=%p, Callback=%p, Data=%p, State=0x%x]\n",
556
- CONN_INDENT, (void *)req, u_cb.ptr, (void *)req->arg,
557
- req->state);
558
- }
559
-
560
- fprintf(out, "\n");
561
-
562
- }
563
-
564
- static void
565
- dumpfunc(const void *k, lcb_size_t nk, const void *v, lcb_size_t nv, void *arg)
566
- {
567
- FILE *out = (FILE *)arg;
568
- mgr_HOST *he = (void *)v;
569
- he_dump(he, out);
570
- (void)nk;(void)k;(void)nv;
571
- }
572
-
573
- /**
574
- * Dumps the connection manager state to stderr
575
- */
576
- LCB_INTERNAL_API
577
- void lcbio_mgr_dump(lcbio_MGR *mgr, FILE *out)
578
- {
579
- if (out == NULL) {
580
- out = stderr;
581
- }
582
-
583
- genhash_iter(mgr->ht, dumpfunc, out);
584
- }