libcouchbase 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/libcouchbase/CMakeLists.txt +8 -6
  5. data/ext/libcouchbase/README.markdown +2 -2
  6. data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
  7. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
  8. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
  9. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
  10. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  11. data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
  12. data/ext/libcouchbase/cmake/defs.mk.in +2 -0
  13. data/ext/libcouchbase/cmake/source_files.cmake +5 -21
  14. data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
  15. data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
  16. data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
  17. data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
  18. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  19. data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
  20. data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
  21. data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
  22. data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
  23. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
  26. data/ext/libcouchbase/src/README.md +2 -0
  27. data/ext/libcouchbase/src/auth-priv.h +0 -1
  28. data/ext/libcouchbase/src/auth.cc +4 -10
  29. data/ext/libcouchbase/src/bootstrap.c +269 -0
  30. data/ext/libcouchbase/src/bootstrap.h +39 -50
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
  37. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  38. data/ext/libcouchbase/src/cbft.cc +27 -22
  39. data/ext/libcouchbase/src/cntl.cc +19 -30
  40. data/ext/libcouchbase/src/connspec.cc +1 -48
  41. data/ext/libcouchbase/src/connspec.h +0 -27
  42. data/ext/libcouchbase/src/dump.cc +2 -2
  43. data/ext/libcouchbase/src/getconfig.cc +33 -7
  44. data/ext/libcouchbase/src/handler.cc +2 -0
  45. data/ext/libcouchbase/src/hostlist.cc +36 -0
  46. data/ext/libcouchbase/src/hostlist.h +62 -41
  47. data/ext/libcouchbase/src/http/http-priv.h +112 -125
  48. data/ext/libcouchbase/src/http/http.cc +30 -15
  49. data/ext/libcouchbase/src/http/http.h +34 -1
  50. data/ext/libcouchbase/src/http/http_io.cc +26 -22
  51. data/ext/libcouchbase/src/instance.cc +23 -94
  52. data/ext/libcouchbase/src/internal.h +26 -52
  53. data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
  54. data/ext/libcouchbase/src/jsparse/parser.h +98 -91
  55. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  56. data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
  57. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  58. data/ext/libcouchbase/src/lcbio/connect.h +2 -9
  59. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  60. data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
  61. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  62. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  63. data/ext/libcouchbase/src/mc/mcreq.h +2 -9
  64. data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
  65. data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
  66. data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
  67. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  68. data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
  69. data/ext/libcouchbase/src/newconfig.cc +6 -6
  70. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  71. data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
  72. data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
  73. data/ext/libcouchbase/src/operations/durability.cc +26 -6
  74. data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
  75. data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
  76. data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
  77. data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
  78. data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
  79. data/ext/libcouchbase/src/operations/stats.cc +8 -3
  80. data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
  81. data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
  82. data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
  83. data/ext/libcouchbase/src/packetutils.c +37 -0
  84. data/ext/libcouchbase/src/packetutils.h +2 -2
  85. data/ext/libcouchbase/src/probes.d +1 -1
  86. data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
  87. data/ext/libcouchbase/src/retryq.cc +4 -4
  88. data/ext/libcouchbase/src/settings.c +0 -3
  89. data/ext/libcouchbase/src/settings.h +0 -5
  90. data/ext/libcouchbase/src/simplestring.c +211 -0
  91. data/ext/libcouchbase/src/simplestring.h +228 -0
  92. data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
  93. data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
  94. data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
  95. data/ext/libcouchbase/src/ssobuf.h +82 -0
  96. data/ext/libcouchbase/src/trace.h +4 -4
  97. data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
  98. data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
  99. data/ext/libcouchbase/src/views/docreq.h +30 -24
  100. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  101. data/ext/libcouchbase/src/views/viewreq.h +13 -43
  102. data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
  103. data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
  104. data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
  105. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  106. data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
  107. data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
  108. data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
  109. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  110. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  111. data/lib/libcouchbase/ext/tasks.rb +6 -2
  112. data/lib/libcouchbase/query_view.rb +1 -1
  113. data/lib/libcouchbase/results_fiber.rb +6 -6
  114. data/lib/libcouchbase/version.rb +1 -1
  115. metadata +26 -26
  116. data/ext/libcouchbase/src/bootstrap.cc +0 -216
  117. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
  118. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
  119. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
  120. data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
  121. data/ext/libcouchbase/src/dns-srv.cc +0 -142
  122. data/ext/libcouchbase/src/errmap.cc +0 -107
  123. data/ext/libcouchbase/src/errmap.h +0 -113
  124. data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
  125. data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
  126. data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
  127. data/ext/libcouchbase/src/mctx-helper.h +0 -51
  128. data/ext/libcouchbase/src/views/viewreq.cc +0 -318
  129. data/ext/libcouchbase/tests/iotests/t_errmap.cc +0 -97
@@ -1,562 +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 "config.h"
19
- #include "connect.h"
20
- #include "ioutils.h"
21
- #include "iotable.h"
22
- #include "settings.h"
23
- #include "timer-ng.h"
24
- #include "timer-cxx.h"
25
- #include <errno.h>
26
-
27
- using namespace lcb::io;
28
-
29
- /* win32 lacks EAI_SYSTEM */
30
- #ifndef EAI_SYSTEM
31
- #define EAI_SYSTEM 0
32
- #endif
33
- #define LOGARGS(conn, lvl) conn->settings, "connection", LCB_LOG_##lvl, __FILE__, __LINE__
34
- static const lcb_host_t *get_loghost(lcbio_SOCKET *s) {
35
- static lcb_host_t host = { "NOHOST", "NOPORT" };
36
- if (!s) { return &host; }
37
- if (!s->info) { return &host; }
38
- return &s->info->ep;
39
- }
40
-
41
- /** Format string arguments for %p%s:%s */
42
- #define CSLOGID(sock) get_loghost(sock)->host, get_loghost(sock)->port, (void*)sock
43
- #define CSLOGFMT "<%s:%s> (SOCK=%p) "
44
-
45
- #define LOGARGS_T(lvl) LOGARGS(this->sock, lvl)
46
- #define CSLOGID_T() CSLOGID(this->sock)
47
-
48
- namespace lcb {
49
- namespace io {
50
- struct Connstart {
51
- Connstart(lcbio_TABLE*, lcb_settings*, const lcb_host_t*,
52
- uint32_t, lcbio_CONNDONE_cb, void*);
53
-
54
- ~Connstart();
55
- void unwatch();
56
- void handler();
57
- void cancel();
58
- void C_connect();
59
-
60
- enum State {
61
- CS_PENDING, CS_CANCELLED, CS_CONNECTED, CS_ERROR
62
- };
63
-
64
- void state_signal(State next_state, lcb_error_t status);
65
- void notify_success();
66
- void notify_error(lcb_error_t err);
67
- bool ensure_sock();
68
- void clear_sock();
69
-
70
- lcbio_CONNDONE_cb user_handler;
71
- void *user_arg;
72
-
73
- lcbio_SOCKET *sock;
74
- lcbio_OSERR syserr;
75
- void *event;
76
- bool ev_active; /* whether the event pointer is active (Event only) */
77
- bool in_uhandler; /* Whether we're inside the user-defined handler */
78
- addrinfo *ai_root;
79
- addrinfo *ai;
80
- State state;
81
- lcb_error_t last_error;
82
- Timer<Connstart, &Connstart::handler> timer;
83
- };
84
- }
85
- }
86
-
87
- void Connstart::unwatch() {
88
- if (sock && ev_active) {
89
- lcb_assert(sock->u.fd != INVALID_SOCKET);
90
- sock->io->E_event_cancel(sock->u.fd, event);
91
- ev_active = false;
92
- }
93
- }
94
-
95
- /**
96
- * Handler invoked to deliver final status for a connection. This will invoke
97
- * the user supplied callback with the relevant status (if it has not been
98
- * cancelled) and then free the CONNSTART object.
99
- */
100
- void Connstart::handler() {
101
- lcb_error_t err;
102
-
103
- if (sock && event) {
104
- unwatch();
105
- sock->io->E_event_destroy(event);
106
- }
107
-
108
- if (state == CS_PENDING) {
109
- /* state was not changed since initial scheduling */
110
- err = LCB_ETIMEDOUT;
111
- } else if (state == CS_CONNECTED) {
112
- /* clear pending error */
113
- err = LCB_SUCCESS;
114
- } else {
115
- if (sock != NULL && last_error == LCB_CONNECT_ERROR) {
116
- err = lcbio_mklcberr(syserr, sock->settings);
117
- } else {
118
- err = last_error;
119
- }
120
- }
121
-
122
- if (state == CS_CANCELLED) {
123
- /* ignore everything. Clean up resources */
124
- goto GT_DTOR;
125
- }
126
-
127
- if (sock) {
128
- lcbio__load_socknames(sock);
129
- if (err == LCB_SUCCESS) {
130
- lcb_log(LOGARGS_T(INFO), CSLOGFMT "Connected established", CSLOGID_T());
131
-
132
- if (sock->settings->tcp_nodelay) {
133
- lcb_error_t ndrc = lcbio_disable_nagle(sock);
134
- if (ndrc != LCB_SUCCESS) {
135
- lcb_log(LOGARGS_T(INFO), CSLOGFMT "Couldn't set TCP_NODELAY", CSLOGID_T());
136
- } else {
137
- lcb_log(LOGARGS_T(DEBUG), CSLOGFMT "Successfuly set TCP_NODELAY", CSLOGID_T());
138
- }
139
- }
140
- } else {
141
- lcb_log(LOGARGS_T(ERR), CSLOGFMT "Failed to establish connection: %s, os errno=%u", CSLOGID_T(), lcb_strerror_short(err), syserr);
142
- }
143
- }
144
-
145
- /** Handler section */
146
- in_uhandler = true;
147
- user_handler(err == LCB_SUCCESS ? sock : NULL, user_arg, err, syserr);
148
- in_uhandler = false;
149
-
150
- GT_DTOR:
151
- delete this;
152
- }
153
-
154
- Connstart::~Connstart() {
155
- timer.release();
156
- if (sock) {
157
- lcbio_unref(sock);
158
- }
159
- if (ai_root) {
160
- freeaddrinfo(ai_root);
161
- }
162
- }
163
-
164
- void Connstart::state_signal(State next_state, lcb_error_t err) {
165
- if (state != CS_PENDING) {
166
- /** State already set */
167
- return;
168
- }
169
-
170
-
171
- if (state == CS_CONNECTED) {
172
- /* clear last errors if we're successful */
173
- last_error = LCB_SUCCESS;
174
- } else if (last_error == LCB_SUCCESS) {
175
- /* set error code only if previous code was not a failure */
176
- last_error = err;
177
- }
178
-
179
- state = next_state;
180
- timer.signal();
181
- }
182
-
183
- void Connstart::notify_success() {
184
- state_signal(CS_CONNECTED, LCB_SUCCESS);
185
- }
186
-
187
- void Connstart::notify_error(lcb_error_t err) {
188
- state_signal(CS_ERROR, err);
189
- }
190
-
191
- /** Cancels and mutes any pending event */
192
- void lcbio_connect_cancel(lcbio_pCONNSTART cs) {
193
- cs->cancel();
194
- }
195
-
196
- void Connstart::cancel() {
197
- if (in_uhandler) {
198
- /* already inside user-defined handler */
199
- return;
200
- }
201
- state = CS_CANCELLED;
202
- handler();
203
- }
204
-
205
-
206
- bool Connstart::ensure_sock() {
207
- lcbio_TABLE *io = sock->io;
208
- int errtmp = 0;
209
-
210
- if (ai == NULL) {
211
- return false;
212
- }
213
-
214
- if (io->is_E()) {
215
- if (sock->u.fd != INVALID_SOCKET) {
216
- /* already have one? */
217
- return true;
218
- }
219
-
220
- while (sock->u.fd == INVALID_SOCKET && ai != NULL) {
221
- sock->u.fd = lcbio_E_ai2sock(io, &ai, &errtmp);
222
- if (sock->u.fd != INVALID_SOCKET) {
223
- lcb_log(LOGARGS_T(DEBUG), CSLOGFMT "Created new socket with FD=%d", CSLOGID_T(), sock->u.fd);
224
- return true;
225
- }
226
- }
227
- } else {
228
- if (sock->u.sd) {
229
- return true;
230
- }
231
-
232
- while (sock->u.sd == NULL && ai != NULL) {
233
- sock->u.sd = lcbio_C_ai2sock(io, &ai, &errtmp);
234
- if (sock->u.sd) {
235
- sock->u.sd->lcbconn = const_cast<lcbio_SOCKET*>(sock);
236
- sock->u.sd->parent = IOT_ARG(io);
237
- return true;
238
- }
239
- }
240
- }
241
-
242
- if (ai == NULL) {
243
- lcbio_mksyserr(IOT_ERRNO(io), &syserr);
244
- return false;
245
- }
246
- return true;
247
- }
248
-
249
- void Connstart::clear_sock() {
250
- lcbio_TABLE *iot = sock->io;
251
- if (ai) {
252
- ai = ai->ai_next;
253
- }
254
-
255
- if (!ai) {
256
- return;
257
- }
258
-
259
- if (iot->is_E()) {
260
- unwatch();
261
- iot->E_close(sock->u.fd);
262
- sock->u.fd = INVALID_SOCKET;
263
- } else {
264
- if (sock->u.sd) {
265
- iot->C_close(sock->u.sd);
266
- sock->u.sd = NULL;
267
- }
268
- }
269
- }
270
-
271
- static void
272
- E_conncb(lcb_socket_t, short events, void *arg)
273
- {
274
- Connstart *cs = reinterpret_cast<Connstart*>(arg);
275
- lcbio_SOCKET *s = cs->sock;
276
- lcbio_TABLE *io = s->io;
277
- int retry_once = 0;
278
- lcbio_CSERR connstatus;
279
- int rv = 0;
280
- addrinfo *ai = NULL;
281
-
282
- GT_NEXTSOCK:
283
- if (!cs->ensure_sock()) {
284
- cs->notify_error(LCB_CONNECT_ERROR);
285
- return;
286
- }
287
-
288
- if (events & LCB_ERROR_EVENT) {
289
- socklen_t errlen = sizeof(int);
290
- int sockerr = 0;
291
- lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Received ERROR_EVENT", CSLOGID(s));
292
- getsockopt(s->u.fd, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &errlen);
293
- lcbio_mksyserr(sockerr, &cs->syserr);
294
- cs->clear_sock();
295
- goto GT_NEXTSOCK;
296
-
297
- } else {
298
- rv = 0;
299
- ai = cs->ai;
300
-
301
- GT_CONNECT:
302
- rv = io->E_connect(s->u.fd, ai->ai_addr, ai->ai_addrlen);
303
- if (rv == 0) {
304
- cs->unwatch();
305
- cs->notify_success();
306
- return;
307
- }
308
- }
309
-
310
- connstatus = lcbio_mkcserr(io->get_errno());
311
- lcbio_mksyserr(io->get_errno(), &cs->syserr);
312
-
313
-
314
- switch (connstatus) {
315
-
316
- case LCBIO_CSERR_INTR:
317
- goto GT_CONNECT;
318
-
319
- case LCBIO_CSERR_CONNECTED:
320
- cs->unwatch();
321
- cs->notify_success();
322
- return;
323
-
324
- case LCBIO_CSERR_BUSY:
325
- lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Scheduling I/O watcher for asynchronous connection completion.", CSLOGID(s));
326
- io->E_event_watch(s->u.fd, cs->event, LCB_WRITE_EVENT, cs, E_conncb);
327
- cs->ev_active = 1;
328
- return;
329
-
330
- case LCBIO_CSERR_EINVAL:
331
- if (!retry_once) {
332
- retry_once = 1;
333
- goto GT_CONNECT;
334
- }
335
- /* fallthrough */
336
-
337
- case LCBIO_CSERR_EFAIL:
338
- default:
339
- /* close the current socket and try again */
340
- lcb_log(LOGARGS(s, TRACE), CSLOGFMT "connect() failed. errno=%d [%s]", CSLOGID(s), IOT_ERRNO(io), strerror(IOT_ERRNO(io)));
341
- cs->clear_sock();
342
- goto GT_NEXTSOCK;
343
- }
344
- }
345
-
346
-
347
- static void
348
- C_conncb(lcb_sockdata_t *sock, int status)
349
- {
350
- lcbio_SOCKET *s = reinterpret_cast<lcbio_SOCKET*>(sock->lcbconn);
351
- Connstart *cs = reinterpret_cast<Connstart*>(s->ctx);
352
-
353
- lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Received completion handler. Status=%d. errno=%d", CSLOGID(s), status, IOT_ERRNO(s->io));
354
-
355
- if (!--s->refcount) {
356
- lcbio__destroy(s);
357
- return;
358
- }
359
-
360
- if (!status) {
361
- if (cs->state == Connstart::CS_PENDING) {
362
- cs->state = Connstart::CS_CONNECTED;
363
- }
364
- cs->handler();
365
- } else {
366
- lcbio_mksyserr(s->io->get_errno(), &cs->syserr);
367
- cs->clear_sock();
368
- cs->C_connect();
369
- }
370
- }
371
-
372
- void Connstart::C_connect()
373
- {
374
- int rv;
375
- bool retry_once = 0;
376
- lcbio_CSERR status;
377
- lcbio_TABLE *io = sock->io;
378
-
379
- GT_NEXTSOCK:
380
- if (!ensure_sock()) {
381
- lcbio_mksyserr(IOT_ERRNO(io), &syserr);
382
- notify_error(LCB_CONNECT_ERROR);
383
- return;
384
- }
385
-
386
- GT_CONNECT:
387
- rv = io->C_connect(sock->u.sd, ai->ai_addr, ai->ai_addrlen, C_conncb);
388
- if (rv == 0) {
389
- lcbio_ref(sock);
390
- return;
391
- }
392
-
393
- lcbio_mksyserr(io->get_errno(), &syserr);
394
- status = lcbio_mkcserr(io->get_errno());
395
- switch (status) {
396
-
397
- case LCBIO_CSERR_INTR:
398
- goto GT_CONNECT;
399
-
400
- case LCBIO_CSERR_CONNECTED:
401
- notify_success();
402
- return;
403
-
404
- case LCBIO_CSERR_BUSY:
405
- return;
406
-
407
- case LCBIO_CSERR_EINVAL:
408
- if (!retry_once) {
409
- retry_once = 1;
410
- goto GT_CONNECT;
411
- }
412
- /* fallthrough */
413
-
414
- case LCBIO_CSERR_EFAIL:
415
- default:
416
- clear_sock();
417
- goto GT_NEXTSOCK;
418
- }
419
- }
420
-
421
- Connstart *
422
- lcbio_connect(lcbio_TABLE *iot, lcb_settings *settings, const lcb_host_t *dest,
423
- uint32_t timeout, lcbio_CONNDONE_cb handler, void *arg)
424
- {
425
- return new Connstart(iot, settings, dest, timeout, handler, arg);
426
- }
427
-
428
- Connstart::Connstart(lcbio_TABLE* iot_, lcb_settings* settings_,
429
- const lcb_host_t *dest, uint32_t timeout,
430
- lcbio_CONNDONE_cb handler, void *arg)
431
- : user_handler(handler), user_arg(arg), sock(NULL), syserr(0),
432
- event(NULL), ev_active(false), in_uhandler(false),
433
- ai_root(NULL), ai(NULL), state(CS_PENDING), last_error(LCB_SUCCESS),
434
- timer(iot_, this) {
435
-
436
- addrinfo hints;
437
- int rv;
438
-
439
- sock = reinterpret_cast<lcbio_SOCKET*>(calloc(1, sizeof(*sock)));
440
-
441
- /** Initialize the socket first */
442
- sock->io = iot_;
443
- sock->settings = settings_;
444
- sock->ctx = this;
445
- sock->refcount = 1;
446
- sock->info = reinterpret_cast<lcbio_CONNINFO*>(calloc(1, sizeof(*sock->info)));
447
- sock->info->ep = *dest;
448
- lcbio_table_ref(sock->io);
449
- lcb_settings_ref(sock->settings);
450
- lcb_list_init(&sock->protos);
451
-
452
- if (iot_->is_E()) {
453
- sock->u.fd = INVALID_SOCKET;
454
- event = iot_->E_event_create();
455
- }
456
-
457
- timer.rearm(timeout);
458
- lcb_log(LOGARGS_T(INFO), CSLOGFMT "Starting. Timeout=%uus", CSLOGID_T(), timeout);
459
-
460
- /** Hostname lookup: */
461
- memset(&hints, 0, sizeof(hints));
462
- hints.ai_flags = AI_PASSIVE;
463
- hints.ai_socktype = SOCK_STREAM;
464
- if (settings_->ipv6 == LCB_IPV6_DISABLED) {
465
- hints.ai_family = AF_INET;
466
- } else if (settings_->ipv6 == LCB_IPV6_ONLY) {
467
- hints.ai_family = AF_INET6;
468
- } else {
469
- hints.ai_family = AF_UNSPEC;
470
- }
471
-
472
- if ((rv = getaddrinfo(dest->host, dest->port, &hints, &ai_root))) {
473
- const char *errstr = rv != EAI_SYSTEM ? gai_strerror(rv) : "";
474
- lcb_log(LOGARGS_T(ERR), CSLOGFMT "Couldn't look up %s (%s) [EAI=%d]", CSLOGID_T(), dest->host, errstr, rv);
475
- notify_error(LCB_UNKNOWN_HOST);
476
- } else {
477
- ai = ai_root;
478
-
479
- /** Figure out how to connect */
480
- if (iot_->is_E()) {
481
- E_conncb(-1, LCB_WRITE_EVENT, this);
482
- } else {
483
- C_connect();
484
- }
485
- }
486
- }
487
-
488
- Connstart *
489
- lcbio_connect_hl(lcbio_TABLE *iot, lcb_settings *settings,
490
- lcb::Hostlist* hl, int rollover, uint32_t timeout,
491
- lcbio_CONNDONE_cb handler, void *arg)
492
- {
493
- const lcb_host_t *cur;
494
- unsigned ii = 0, hlmax = hl->size();
495
-
496
- while ( (cur = hl->next(rollover)) && ii++ < hlmax) {
497
- Connstart *ret = lcbio_connect(
498
- iot, settings, cur, timeout, handler, arg);
499
- if (ret) {
500
- return ret;
501
- }
502
- }
503
-
504
- return NULL;
505
- }
506
-
507
- lcbio_SOCKET *
508
- lcbio_wrap_fd(lcbio_pTABLE iot, lcb_settings *settings, lcb_socket_t fd)
509
- {
510
- lcbio_SOCKET *ret = reinterpret_cast<lcbio_SOCKET*>(calloc(1, sizeof(*ret)));
511
- lcbio_CONNDONE_cb *ci = reinterpret_cast<lcbio_CONNDONE_cb*>(calloc(1, sizeof(*ci)));
512
-
513
- if (ret == NULL || ci == NULL) {
514
- free(ret);
515
- free(ci);
516
- return NULL;
517
- }
518
-
519
- assert(iot->model = LCB_IOMODEL_EVENT);
520
-
521
- lcb_list_init(&ret->protos);
522
- ret->settings = settings;
523
- ret->io = iot;
524
- ret->refcount = 1;
525
- ret->u.fd = fd;
526
-
527
- lcbio_table_ref(ret->io);
528
- lcb_settings_ref(ret->settings);
529
- lcbio__load_socknames(ret);
530
- return ret;
531
- }
532
-
533
- void
534
- lcbio_shutdown(lcbio_SOCKET *s)
535
- {
536
- lcbio_TABLE *io = s->io;
537
-
538
- lcbio__protoctx_delall(s);
539
- if (IOT_IS_EVENT(io)) {
540
- if (s->u.fd != INVALID_SOCKET) {
541
- io->E_close(s->u.fd);
542
- s->u.fd = INVALID_SOCKET;
543
- }
544
- } else {
545
- if (s->u.sd) {
546
- io->C_close(s->u.sd);
547
- s->u.sd = NULL;
548
- }
549
- }
550
- }
551
-
552
- void
553
- lcbio__destroy(lcbio_SOCKET *s)
554
- {
555
- lcbio_shutdown(s);
556
- if (s->info) {
557
- free(s->info);
558
- }
559
- lcbio_table_unref(s->io);
560
- lcb_settings_unref(s->settings);
561
- free(s);
562
- }