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
@@ -28,7 +28,7 @@ provider libcouchbase {
28
28
  uint16_t, /* return code (from libcouchbase) */
29
29
  const char*, /* key */
30
30
  size_t, /* nkey */
31
- const void*, /* bytes */
31
+ const char*, /* bytes */
32
32
  size_t, /* nbytes */
33
33
  uint32_t, /* flags */
34
34
  uint64_t, /* cas */
@@ -395,7 +395,7 @@ dump_ropebuf(const rdb_ROPEBUF *buf, FILE *fp)
395
395
  rdb_ROPESEG *seg = LCB_LIST_ITEM(llcur, rdb_ROPESEG, llnode);
396
396
  fprintf(fp, "%sSEG=%p\n", indent, (void*)seg);
397
397
  fprintf(fp, "%sALLOCATOR=%p [%u]\n", indent, (void*)seg->allocator, seg->allocid);
398
- fprintf(fp, "%sBUFROOT=%p\n", indent, seg->root);
398
+ fprintf(fp, "%sBUFROOT=%p\n", indent, (void *)seg->root);
399
399
  fprintf(fp, "%sALLOC SIZE: %u\n", indent, seg->nalloc);
400
400
  fprintf(fp, "%sDATA SIZE: %u\n", indent, seg->nused);
401
401
  fprintf(fp, "%sDATS OFFSET: %u\n", indent, seg->start);
@@ -20,8 +20,8 @@
20
20
  int
21
21
  lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t err)
22
22
  {
23
- lcb_RETRYCMDOPTS policy;
24
- lcb_RETRYMODEOPTS mode;
23
+ unsigned policy;
24
+ unsigned mode;
25
25
  protocol_binary_request_header hdr;
26
26
 
27
27
  mcreq_read_hdr(pkt, &hdr);
@@ -70,7 +70,6 @@ lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t
70
70
 
71
71
  /* get is a safe operation which may be retried */
72
72
  case PROTOCOL_BINARY_CMD_GET:
73
- case PROTOCOL_BINARY_CMD_GETKQ:
74
73
  case PROTOCOL_BINARY_CMD_SUBDOC_GET:
75
74
  case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS:
76
75
  case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP:
@@ -37,7 +37,13 @@ struct lcb::RetryOp : mc_EPKTDATUM, SchedNode, TmoNode {
37
37
  hrtime_t trytime; /**< Next retry time */
38
38
  mc_PACKET *pkt;
39
39
  lcb_error_t origerr;
40
- RetryOp();
40
+ errmap::RetrySpec *spec;
41
+ RetryOp(errmap::RetrySpec *spec);
42
+ ~RetryOp() {
43
+ if (spec != NULL) {
44
+ spec->unref();
45
+ }
46
+ }
41
47
  };
42
48
 
43
49
  static RetryOp *from_schednode(lcb_list_t *ll) {
@@ -79,10 +85,24 @@ RetryQueue::update_trytime(RetryOp *op, hrtime_t now)
79
85
  if (!now) {
80
86
  now = gethrtime();
81
87
  }
82
- op->trytime = now + (hrtime_t) (
83
- (float)get_retry_interval() *
84
- (float)op->pkt->retries *
85
- (float)settings->retry_backoff);
88
+
89
+ if (op->spec) {
90
+ uint32_t us_trytime = op->spec->get_next_interval(op->pkt->retries - 1);
91
+ if (op->pkt->retries == 1) {
92
+ us_trytime += op->spec->after;
93
+ }
94
+ if (!us_trytime) {
95
+ goto GT_DEFAULT;
96
+ }
97
+ op->trytime = now + (LCB_US2NS(us_trytime));
98
+ } else {
99
+ GT_DEFAULT:
100
+ op->trytime = now + (hrtime_t) (
101
+ (float)get_retry_interval() *
102
+ (float)op->pkt->retries *
103
+ (float)settings->retry_backoff);
104
+
105
+ }
86
106
  }
87
107
 
88
108
  /** Comparison routine for sorting by timeout */
@@ -139,7 +159,7 @@ RetryQueue::fail(RetryOp *op, lcb_error_t err)
139
159
  PROTOCOL_BINARY_RESPONSE_EINVAL);
140
160
 
141
161
  assign_error(op, err);
142
- lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue with error code 0x%x", op->pkt->opaque, op->origerr);
162
+ lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue: %s", op->pkt->opaque, lcb_strerror_short(op->origerr));
143
163
 
144
164
  mcreq_dispatch_response(&tmpsrv, op->pkt, &resp, op->origerr);
145
165
  op->pkt->flags |= MCREQ_F_FLUSHED|MCREQ_F_INVOKED;
@@ -231,8 +251,8 @@ RetryQueue::flush(bool throttle)
231
251
  * configuration (i.e. the attempt has not been throttled) then
232
252
  * keep the command in there until it has a chance to be scheduled.
233
253
  */
234
- lcb_bootstrap_common(get_instance(), LCB_BS_REFRESH_THROTTLE);
235
- if (lcb_confmon_is_refreshing(get_instance()->confmon) ||
254
+ get_instance()->bootstrap(lcb::BS_REFRESH_THROTTLE);
255
+ if (get_instance()->confmon->is_refreshing() ||
236
256
  settings->retry[LCB_RETRY_ON_MISSINGNODE]) {
237
257
 
238
258
  lcb_list_delete(static_cast<SchedNode*>(op));
@@ -276,22 +296,40 @@ static void op_dtorfn(mc_EPKTDATUM *d) {
276
296
  delete static_cast<RetryOp*>(d);
277
297
  }
278
298
 
279
- RetryOp::RetryOp() {
280
- memset(this, 0, sizeof *this);
299
+ RetryOp::RetryOp(errmap::RetrySpec *spec_)
300
+ : mc_EPKTDATUM(), start(0), trytime(0), pkt(NULL), origerr(LCB_SUCCESS),
301
+ spec(spec_) {
281
302
  mc_EPKTDATUM::dtorfn = op_dtorfn;
282
303
  mc_EPKTDATUM::key = RETRY_PKT_KEY;
304
+
305
+ if (spec != NULL) {
306
+ spec->ref();
307
+ }
283
308
  }
284
309
 
285
310
  void
286
- RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err, int options)
311
+ RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err,
312
+ errmap::RetrySpec *spec, int options)
287
313
  {
288
314
  RetryOp *op;
289
315
  mc_EPKTDATUM *d = mcreq_epkt_find(pkt, RETRY_PKT_KEY);
290
316
  if (d) {
291
317
  op = static_cast<RetryOp *>(d);
292
318
  } else {
293
- op = new RetryOp();
319
+ op = new RetryOp(NULL);
294
320
  op->start = MCREQ_PKT_RDATA(&pkt->base)->start;
321
+ if (spec) {
322
+ op->spec = spec;
323
+ spec->ref();
324
+
325
+ if (spec->max_duration && spec->max_duration < settings->operation_timeout) {
326
+ // Offset the start by the difference between the duration and
327
+ // the timeout. We really use this number only for calculating
328
+ // the timeout, so it shouldn't hurt to fake it.
329
+ uint32_t diff = settings->operation_timeout - op->spec->max_duration;
330
+ op->start -= LCB_US2NS(diff);
331
+ }
332
+ }
295
333
  mcreq_epkt_insert(pkt, op);
296
334
  }
297
335
 
@@ -320,7 +358,7 @@ RetryQueue::nmvadd(mc_EXPACKET *detchpkt)
320
358
  if (settings->nmv_retry_imm) {
321
359
  flags = RETRY_SCHED_IMM;
322
360
  }
323
- add(detchpkt, LCB_NOT_MY_VBUCKET, flags);
361
+ add(detchpkt, LCB_NOT_MY_VBUCKET, NULL, flags);
324
362
  }
325
363
 
326
364
  static void
@@ -332,7 +370,7 @@ fallback_handler(mc_CMDQUEUE *cq, mc_PACKET *pkt)
332
370
 
333
371
  void RetryQueue::add_fallback(mc_PACKET *pkt) {
334
372
  mc_PACKET *copy = mcreq_renew_packet(pkt);
335
- add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, RETRY_SCHED_IMM);
373
+ add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, NULL, RETRY_SCHED_IMM);
336
374
  }
337
375
 
338
376
  void
@@ -72,8 +72,8 @@ public:
72
72
  * it may _not_ be used for memcached buckets (which is typically OK, as we only
73
73
  * map things here as a response for a not-my-vbucket).
74
74
  */
75
- void add(mc_EXPACKET *detchpkt, lcb_error_t err) {
76
- add(detchpkt, err, 0);
75
+ void add(mc_EXPACKET *detchpkt, lcb_error_t err, errmap::RetrySpec *spec) {
76
+ add(detchpkt, err, spec, 0);
77
77
  }
78
78
 
79
79
  /**
@@ -151,7 +151,7 @@ private:
151
151
  enum AddOptions {
152
152
  RETRY_SCHED_IMM = 0x01
153
153
  };
154
- void add(mc_EXPACKET *pkt, lcb_error_t, int options);
154
+ void add(mc_EXPACKET *pkt, lcb_error_t, errmap::RetrySpec*, int options);
155
155
 
156
156
  /** List of operations in retry ordering. Sorted by 'crtime' */
157
157
  lcb_list_t schedops;
@@ -57,6 +57,9 @@ void lcb_default_settings(lcb_settings *settings)
57
57
  settings->tcp_nodelay = LCB_DEFAULT_TCP_NODELAY;
58
58
  settings->retry_nmv_interval = LCB_DEFAULT_RETRY_NMV_INTERVAL;
59
59
  settings->vb_noguess = LCB_DEFAULT_VB_NOGUESS;
60
+ settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
61
+ settings->tcp_keepalive = LCB_DEFAULT_TCP_KEEPALIVE;
62
+ settings->send_hello = 1;
60
63
  }
61
64
 
62
65
  LCB_INTERNAL_API
@@ -67,6 +70,7 @@ lcb_settings_new(void)
67
70
  lcb_default_settings(settings);
68
71
  settings->refcount = 1;
69
72
  settings->auth = lcbauth_new();
73
+ settings->errmap = lcb_errmap_new();
70
74
  return settings;
71
75
  }
72
76
 
@@ -83,6 +87,7 @@ lcb_settings_unref(lcb_settings *settings)
83
87
  free(settings->client_string);
84
88
 
85
89
  lcbauth_unref(settings->auth);
90
+ lcb_errmap_free(settings->errmap);
86
91
 
87
92
  if (settings->ssl_ctx) {
88
93
  lcbio_ssl_free(settings->ssl_ctx);
@@ -84,9 +84,12 @@
84
84
  #define LCB_DEFAULT_RETRY_NMV_INTERVAL LCB_MS2US(100)
85
85
  #define LCB_DEFAULT_VB_NOGUESS 1
86
86
  #define LCB_DEFAULT_TCP_NODELAY 1
87
+ #define LCB_DEFAULT_SELECT_BUCKET 1
88
+ #define LCB_DEFAULT_TCP_KEEPALIVE 1
87
89
 
88
90
  #include "config.h"
89
91
  #include <libcouchbase/couchbase.h>
92
+ #include "errmap.h"
90
93
 
91
94
  #ifdef __cplusplus
92
95
  extern "C" {
@@ -128,6 +131,9 @@ typedef struct lcb_settings_st {
128
131
  * updates. */
129
132
  lcb_U32 bc_http_stream_time;
130
133
 
134
+ /** Time to wait in between background config polls. 0 disables this */
135
+ lcb_U32 config_poll_interval;
136
+
131
137
  unsigned bc_http_urltype : 4;
132
138
 
133
139
  /** Don't guess next vbucket server. Mainly for testing */
@@ -148,6 +154,10 @@ typedef struct lcb_settings_st {
148
154
  unsigned ipv6 : 2;
149
155
  unsigned tcp_nodelay : 1;
150
156
  unsigned readj_ts_wait : 1;
157
+ unsigned use_errmap : 1;
158
+ unsigned select_bucket : 1;
159
+ unsigned tcp_keepalive : 1;
160
+ unsigned send_hello : 1;
151
161
 
152
162
  short max_redir;
153
163
  unsigned refcount;
@@ -165,6 +175,7 @@ typedef struct lcb_settings_st {
165
175
  void (*dtorcb)(const void *);
166
176
  void *dtorarg;
167
177
  char *client_string;
178
+ lcb_pERRMAP errmap;
168
179
  lcb_U32 retry_nmv_interval;
169
180
  } lcb_settings;
170
181
 
@@ -137,6 +137,7 @@ async_write(void *arg)
137
137
  {
138
138
  lcbio_CSSL *cs = arg;
139
139
  appdata_encode(cs);
140
+ schedule_wants(cs);
140
141
  appdata_free_flushed(cs);
141
142
  }
142
143
 
@@ -156,7 +156,9 @@ iotssl_log_errors(lcbio_XSSL *xs)
156
156
  if (ERR_GET_LIB(curerr) == ERR_LIB_SSL) {
157
157
  switch (ERR_GET_REASON(curerr)) {
158
158
  case SSL_R_CERTIFICATE_VERIFY_FAILED:
159
+ #ifdef SSL_R_MISSING_VERIFY_MESSAGE
159
160
  case SSL_R_MISSING_VERIFY_MESSAGE:
161
+ #endif
160
162
  xs->errcode = LCB_SSL_CANTVERIFY;
161
163
  break;
162
164
 
@@ -16,7 +16,6 @@
16
16
  */
17
17
 
18
18
  #include "ssl_iot_common.h"
19
- #include "simplestring.h"
20
19
  #include <openssl/err.h>
21
20
  /**
22
21
  * Event-Style SSL Wrapping.
@@ -105,7 +105,7 @@ bool urldecode(Ti first, Ti last, To out, size_t& nout) {
105
105
 
106
106
  inline bool
107
107
  urldecode(const char *input, char *output) {
108
- const char *endp = NULL;
108
+ const char *endp = input + strlen(input);
109
109
  size_t nout = 0;
110
110
  if (urldecode(input, endp, output, nout)) {
111
111
  output[nout] = '\0';
@@ -40,11 +40,11 @@
40
40
 
41
41
  #define TRACE_BEGIN_COMMON(TGT, req, cmd, ...) \
42
42
  TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
43
- (cmd)->key.contig.bytes, (cmd)->key.contig.nbytes, ## __VA_ARGS__)
43
+ (const char *)((cmd)->key.contig.bytes), (cmd)->key.contig.nbytes, ## __VA_ARGS__)
44
44
 
45
45
  #define TRACE_BEGIN_SIMPLE(TGT, req, cmd) \
46
46
  TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
47
- (cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
47
+ (const char *)(cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
48
48
 
49
49
  #define TRACE_END_COMMON(TGT, mcresp, resp, ...) \
50
50
  TGT(mcresp->opaque(), 0, mcresp->opcode(), (resp)->rc, (const char *)(resp)->key, (resp)->nkey, \
@@ -58,7 +58,7 @@
58
58
 
59
59
  #define TRACE_GET_END(mcresp, resp) \
60
60
  TRACE(TRACE_END_COMMON(LIBCOUCHBASE_GET_END, mcresp, resp, \
61
- (char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
61
+ (const char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
62
62
  mcresp->datatype()))
63
63
 
64
64
  #define TRACE_UNLOCK_BEGIN(req, cmd) TRACE(TRACE_BEGIN_SIMPLE(LIBCOUCHBASE_UNLOCK_BEGIN, req, cmd))
@@ -66,7 +66,7 @@
66
66
 
67
67
  #define TRACE_STORE_BEGIN(req, cmd) \
68
68
  TRACE(TRACE_BEGIN_COMMON(LIBCOUCHBASE_STORE_BEGIN, req, cmd, \
69
- ( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
69
+ (const char *)( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
70
70
  ( (cmd)->value.vtype == LCB_KV_IOV ? 0 : (cmd)->value.u_buf.contig.nbytes ),\
71
71
  (cmd)->flags, (cmd)->cas, (req)->request.datatype, (cmd)->exptime))
72
72
 
@@ -26,7 +26,6 @@
26
26
  #include "json-inl.h"
27
27
  #include "hash.h"
28
28
  #include "crc32.h"
29
- #include "simplestring.h"
30
29
 
31
30
  #define STRINGIFY_(X) #X
32
31
  #define STRINGIFY(X) STRINGIFY_(X)
@@ -1367,15 +1366,12 @@ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
1367
1366
  }
1368
1367
  }
1369
1368
 
1370
- if (!vb->ndatasrv) {
1371
- vb->errstr = "No data servers in list";
1372
- return -1;
1373
- }
1374
-
1375
- vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
1376
- if (!vb->vbuckets) {
1377
- vb->errstr = "Couldn't allocate vbucket array";
1378
- return -1;
1369
+ if (vb->nvb) {
1370
+ vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
1371
+ if (!vb->vbuckets) {
1372
+ vb->errstr = "Couldn't allocate vbucket array";
1373
+ return -1;
1374
+ }
1379
1375
  }
1380
1376
 
1381
1377
  for (ii = 0; ii < vb->nvb; ii++) {
@@ -2,56 +2,53 @@
2
2
  #include "internal.h"
3
3
  #include "sllist-inl.h"
4
4
 
5
+ using namespace lcb::docreq;
6
+
5
7
  static void docreq_handler(void *arg);
6
- static void invoke_pending(lcb_DOCQUEUE*);
8
+ static void invoke_pending(Queue*);
7
9
  static void doc_callback(lcb_t,int, const lcb_RESPBASE *);
8
10
 
9
11
  #define MAX_PENDING_DOCREQ 10
10
12
  #define MIN_SCHED_SIZE 5
11
13
  #define DOCQ_DELAY_US 200000
12
14
 
13
- #define DOCQ_REF(q) (q)->refcount++
14
- #define DOCQ_UNREF(q) if (!--(q)->refcount) { docq_free(q); }
15
-
16
- lcb_DOCQUEUE *
17
- lcbdocq_create(lcb_t instance)
18
- {
19
- lcb_DOCQUEUE *q = calloc(1, sizeof *q);
20
- q->timer = lcbio_timer_new(instance->iotable, q, docreq_handler);
21
- q->refcount = 1;
22
- q->instance = instance;
23
- q->max_pending_response = MAX_PENDING_DOCREQ;
24
- q->min_batch_size = MIN_SCHED_SIZE;
25
- return q;
15
+ Queue::Queue(lcb_t instance_)
16
+ : instance(instance_),
17
+ parent(NULL),
18
+ timer(lcbio_timer_new(instance->iotable, this, docreq_handler)),
19
+ cb_ready(NULL), cb_throttle(NULL),
20
+ n_awaiting_schedule(0),
21
+ n_awaiting_response(0),
22
+ max_pending_response(MAX_PENDING_DOCREQ),
23
+ min_batch_size(MIN_SCHED_SIZE),
24
+ cancelled(false),
25
+ refcount(1)
26
+ {
27
+
28
+ memset(&pending_gets, 0, sizeof pending_gets);
29
+ memset(&cb_queue, 0, sizeof cb_queue);
26
30
  }
27
31
 
28
- static void
29
- docq_free(lcb_DOCQUEUE *q)
30
- {
31
- lcbdocq_cancel(q);
32
- lcbio_timer_destroy(q->timer);
33
- free(q);
32
+ Queue::~Queue() {
33
+ cancel();
34
+ lcbio_timer_destroy(timer);
34
35
  }
35
36
 
36
- void
37
- lcbdocq_unref(lcb_DOCQUEUE *q)
38
- {
39
- DOCQ_UNREF(q);
37
+ void Queue::unref() {
38
+ if (!--refcount) {
39
+ delete this;
40
+ }
40
41
  }
41
42
 
42
- void
43
- lcbdocq_cancel(lcb_DOCQUEUE *q)
44
- {
45
- if (!q->cancelled) {
46
- q->cancelled = 1;
47
- }
43
+ void Queue::cancel() {
44
+ cancelled = true;
48
45
  }
49
46
 
50
47
  /* Calling this function ensures that the request will be scheduled in due
51
48
  * time. This may be done at the next event loop iteration, or after a delay
52
49
  * depending on how many items are actually found within the queue. */
53
50
  static void
54
- docq_poke(lcb_DOCQUEUE *q)
51
+ docq_poke(Queue *q)
55
52
  {
56
53
  if (q->n_awaiting_response < q->max_pending_response) {
57
54
  if (q->n_awaiting_schedule > q->min_batch_size) {
@@ -65,27 +62,26 @@ docq_poke(lcb_DOCQUEUE *q)
65
62
  }
66
63
  }
67
64
 
68
- void
69
- lcbdocq_add(lcb_DOCQUEUE *q, lcb_DOCQREQ *req)
65
+ void Queue::add(DocRequest *req)
70
66
  {
71
- sllist_append(&q->pending_gets, &req->slnode);
72
- q->n_awaiting_schedule++;
73
- req->parent = q;
67
+ sllist_append(&pending_gets, &req->slnode);
68
+ n_awaiting_schedule++;
69
+ req->parent = this;
74
70
  req->ready = 0;
75
- DOCQ_REF(q);
76
- docq_poke(q);
71
+ ref();
72
+ docq_poke(this);
77
73
  }
78
74
 
79
75
  static void
80
76
  docreq_handler(void *arg)
81
77
  {
82
- lcb_DOCQUEUE *q = arg;
78
+ Queue *q = reinterpret_cast<Queue*>(arg);
83
79
  sllist_iterator iter;
84
80
  lcb_t instance = q->instance;
85
81
 
86
82
  lcb_sched_enter(instance);
87
83
  SLLIST_ITERFOR(&q->pending_gets, &iter) {
88
- lcb_DOCQREQ *cont = SLLIST_ITEM(iter.cur, lcb_DOCQREQ, slnode);
84
+ DocRequest *cont = SLLIST_ITEM(iter.cur, DocRequest, slnode);
89
85
 
90
86
  if (q->n_awaiting_response > q->max_pending_response) {
91
87
  lcbio_timer_rearm(q->timer, DOCQ_DELAY_US);
@@ -136,13 +132,12 @@ docreq_handler(void *arg)
136
132
  /* Invokes the callback on all requests which are ready, until a request which
137
133
  * is not yet ready is reached. */
138
134
  static void
139
- invoke_pending(lcb_DOCQUEUE *q)
135
+ invoke_pending(Queue *q)
140
136
  {
141
137
  sllist_iterator iter = { NULL };
142
-
143
- DOCQ_REF(q);
138
+ q->ref();
144
139
  SLLIST_ITERFOR(&q->cb_queue, &iter) {
145
- lcb_DOCQREQ *dreq = SLLIST_ITEM(iter.cur, lcb_DOCQREQ, slnode);
140
+ DocRequest *dreq = SLLIST_ITEM(iter.cur, DocRequest, slnode);
146
141
  void *bufh = NULL;
147
142
 
148
143
  if (dreq->ready == 0) {
@@ -157,21 +152,21 @@ invoke_pending(lcb_DOCQUEUE *q)
157
152
 
158
153
  q->cb_ready(q, dreq);
159
154
  if (bufh) {
160
- lcb_backbuf_unref(bufh);
155
+ lcb_backbuf_unref(reinterpret_cast<lcb_BACKBUF>(bufh));
161
156
  }
162
- DOCQ_UNREF(q);
157
+ q->unref();
163
158
  }
164
- DOCQ_UNREF(q);
159
+ q->unref();
165
160
  }
166
161
 
167
162
  static void
168
- doc_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
163
+ doc_callback(lcb_t, int, const lcb_RESPBASE *rb)
169
164
  {
170
165
  const lcb_RESPGET *rg = (const lcb_RESPGET *)rb;
171
- lcb_DOCQREQ *dreq = rb->cookie;
172
- lcb_DOCQUEUE *q = dreq->parent;
166
+ DocRequest *dreq = reinterpret_cast<DocRequest*>(rb->cookie);
167
+ Queue *q = dreq->parent;
173
168
 
174
- DOCQ_REF(q);
169
+ q->ref();
175
170
 
176
171
  q->n_awaiting_response--;
177
172
  dreq->docresp = *rg;
@@ -182,13 +177,12 @@ doc_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
182
177
  /* Reference the response data, since we might not be invoking this right
183
178
  * away */
184
179
  if (rg->rc == LCB_SUCCESS) {
185
- lcb_backbuf_ref(dreq->docresp.bufh);
180
+ lcb_backbuf_ref(reinterpret_cast<lcb_BACKBUF>(dreq->docresp.bufh));
186
181
  }
187
182
 
188
183
  /* Ensure the invoke_pending doesn't destroy us */
189
184
  invoke_pending(q);
190
185
  docq_poke(q);
191
186
 
192
- DOCQ_UNREF(q);
193
- (void)instance; (void)cbtype;
187
+ q->unref();
194
188
  }