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
@@ -0,0 +1,474 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2013 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 "internal.h"
19
+ #include "clconfig.h"
20
+ #define LOGARGS(mon, lvlbase) mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__
21
+ #define LOG(mon, lvlbase, msg) lcb_log(mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__, msg)
22
+
23
+ static void async_stop(void *);
24
+ static void async_start(void *);
25
+ static int do_next_provider(lcb_confmon *mon);
26
+ static void invoke_listeners(lcb_confmon *mon,
27
+ clconfig_event_t event,
28
+ clconfig_info *info);
29
+
30
+ #define IS_REFRESHING(mon) ((mon)->state & CONFMON_S_ACTIVE)
31
+
32
+ static clconfig_provider *next_active(lcb_confmon *mon, clconfig_provider *cur)
33
+ {
34
+ if (!LCB_LIST_HAS_NEXT((lcb_list_t *)&mon->active_providers, &cur->ll)) {
35
+ return NULL;
36
+ }
37
+ return LCB_LIST_ITEM(cur->ll.next, clconfig_provider, ll);
38
+ }
39
+ static clconfig_provider *first_active(lcb_confmon *mon)
40
+ {
41
+ if (LCB_LIST_IS_EMPTY((lcb_list_t *)&mon->active_providers)) {
42
+ return NULL;
43
+ }
44
+ return LCB_LIST_ITEM(mon->active_providers.next, clconfig_provider, ll);
45
+ }
46
+
47
+ static const char *
48
+ provider_string(clconfig_method_t type) {
49
+ if (type == LCB_CLCONFIG_HTTP) { return "HTTP"; }
50
+ if (type == LCB_CLCONFIG_CCCP) { return "CCCP"; }
51
+ if (type == LCB_CLCONFIG_FILE) { return "FILE"; }
52
+ if (type == LCB_CLCONFIG_MCRAW) { return "MCRAW"; }
53
+ if (type == LCB_CLCONFIG_USER) { return "USER"; }
54
+ return "";
55
+ }
56
+
57
+ lcb_confmon* lcb_confmon_create(lcb_settings *settings, lcbio_pTABLE iot)
58
+ {
59
+ int ii;
60
+ lcb_confmon * mon = calloc(1, sizeof(*mon));
61
+ mon->settings = settings;
62
+ mon->iot = iot;
63
+ lcb_list_init(&mon->listeners);
64
+ lcb_clist_init(&mon->active_providers);
65
+ lcbio_table_ref(mon->iot);
66
+ lcb_settings_ref(mon->settings);
67
+
68
+ mon->all_providers[LCB_CLCONFIG_FILE] = lcb_clconfig_create_file(mon);
69
+ mon->all_providers[LCB_CLCONFIG_CCCP] = lcb_clconfig_create_cccp(mon);
70
+ mon->all_providers[LCB_CLCONFIG_HTTP] = lcb_clconfig_create_http(mon);
71
+ mon->all_providers[LCB_CLCONFIG_USER] = lcb_clconfig_create_user(mon);
72
+ mon->all_providers[LCB_CLCONFIG_MCRAW] = lcb_clconfig_create_mcraw(mon);
73
+
74
+ for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
75
+ mon->all_providers[ii]->parent = mon;
76
+ }
77
+ mon->as_stop = lcbio_timer_new(iot, mon, async_stop);
78
+ mon->as_start = lcbio_timer_new(iot, mon, async_start);
79
+ return mon;
80
+ }
81
+
82
+ void lcb_confmon_prepare(lcb_confmon *mon)
83
+ {
84
+ int ii;
85
+
86
+ memset(&mon->active_providers, 0, sizeof(mon->active_providers));
87
+ lcb_clist_init(&mon->active_providers);
88
+
89
+ lcb_log(LOGARGS(mon, DEBUG), "Preparing providers (this may be called multiple times)");
90
+
91
+ for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
92
+ clconfig_provider *cur = mon->all_providers[ii];
93
+ if (cur) {
94
+ if (cur->enabled) {
95
+ lcb_clist_append(&mon->active_providers, &cur->ll);
96
+ lcb_log(LOGARGS(mon, DEBUG), "Provider %s is ENABLED", provider_string(cur->type));
97
+ } else if (cur->pause){
98
+ cur->pause(cur);
99
+ lcb_log(LOGARGS(mon, DEBUG), "Provider %s is DISABLED", provider_string(cur->type));
100
+ }
101
+ }
102
+ }
103
+
104
+ lcb_assert(LCB_CLIST_SIZE(&mon->active_providers));
105
+ mon->cur_provider = first_active(mon);
106
+ }
107
+
108
+ void lcb_confmon_destroy(lcb_confmon *mon)
109
+ {
110
+ unsigned int ii;
111
+
112
+ if (mon->as_start) {
113
+ lcbio_timer_destroy(mon->as_start);
114
+ }
115
+
116
+ if (mon->as_stop) {
117
+ lcbio_timer_destroy(mon->as_stop);
118
+ }
119
+
120
+ mon->as_start = NULL;
121
+ mon->as_stop = NULL;
122
+
123
+ if (mon->config) {
124
+ lcb_clconfig_decref(mon->config);
125
+ mon->config = NULL;
126
+ }
127
+
128
+ for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
129
+ clconfig_provider *provider = mon->all_providers[ii];
130
+ if (provider == NULL) {
131
+ continue;
132
+ }
133
+
134
+ provider->shutdown(provider);
135
+ mon->all_providers[ii] = NULL;
136
+ }
137
+
138
+ lcbio_table_unref(mon->iot);
139
+ lcb_settings_unref(mon->settings);
140
+
141
+ free(mon);
142
+ }
143
+
144
+ static int do_set_next(lcb_confmon *mon, clconfig_info *info, int notify_miss)
145
+ {
146
+ unsigned ii;
147
+
148
+ if (mon->config) {
149
+ lcbvb_CHANGETYPE chstatus = LCBVB_NO_CHANGES;
150
+ lcbvb_CONFIGDIFF *diff = lcbvb_compare(mon->config->vbc, info->vbc);
151
+
152
+ if (!diff) {
153
+ lcb_log(LOGARGS(mon, DEBUG), "Couldn't create vbucket diff");
154
+ return 0;
155
+ }
156
+
157
+ chstatus = lcbvb_get_changetype(diff);
158
+ lcbvb_free_diff(diff);
159
+
160
+ if (chstatus == 0 || lcb_clconfig_compare(mon->config, info) >= 0) {
161
+ const lcbvb_CONFIG *ca, *cb;
162
+
163
+ ca = mon->config->vbc;
164
+ cb = info->vbc;
165
+
166
+ lcb_log(LOGARGS(mon, INFO), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(info->origin), ca->revid, cb->revid);
167
+ if (notify_miss) {
168
+ invoke_listeners(mon, CLCONFIG_EVENT_GOT_ANY_CONFIG, info);
169
+ }
170
+ return 0;
171
+ }
172
+ }
173
+
174
+ lcb_log(LOGARGS(mon, INFO), "Setting new configuration. Received via %s", provider_string(info->origin));
175
+
176
+ if (mon->config) {
177
+ /** DECREF the old one */
178
+ lcb_clconfig_decref(mon->config);
179
+ }
180
+
181
+ for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
182
+ clconfig_provider *cur = mon->all_providers[ii];
183
+ if (cur && cur->enabled && cur->config_updated) {
184
+ cur->config_updated(cur, info->vbc);
185
+ }
186
+ }
187
+
188
+ lcb_clconfig_incref(info);
189
+ mon->config = info;
190
+ lcb_confmon_stop(mon);
191
+
192
+ invoke_listeners(mon, CLCONFIG_EVENT_GOT_NEW_CONFIG, info);
193
+
194
+ return 1;
195
+ }
196
+
197
+ void lcb_confmon_provider_failed(clconfig_provider *provider,
198
+ lcb_error_t reason)
199
+ {
200
+ lcb_confmon *mon = provider->parent;
201
+
202
+ lcb_log(LOGARGS(mon, INFO), "Provider '%s' failed", provider_string(provider->type));
203
+
204
+ if (provider != mon->cur_provider) {
205
+ lcb_log(LOGARGS(mon, TRACE), "Ignoring failure. Current=%p (%s)", (void*)mon->cur_provider, provider_string(mon->cur_provider->type));
206
+ return;
207
+ }
208
+ if (!lcb_confmon_is_refreshing(mon)) {
209
+ lcb_log(LOGARGS(mon, DEBUG), "Ignoring failure. Refresh not active");
210
+ }
211
+
212
+ if (reason != LCB_SUCCESS) {
213
+ if (mon->settings->detailed_neterr && mon->last_error != LCB_SUCCESS) {
214
+ /* Filter out any artificial 'connect error' or 'network error' codes */
215
+ if (reason != LCB_CONNECT_ERROR && reason != LCB_NETWORK_ERROR) {
216
+ mon->last_error = reason;
217
+ }
218
+ } else {
219
+ mon->last_error = reason;
220
+ }
221
+ }
222
+
223
+ mon->cur_provider = next_active(mon, mon->cur_provider);
224
+
225
+ if (!mon->cur_provider) {
226
+ LOG(mon, TRACE, "Maximum provider reached. Resetting index");
227
+ invoke_listeners(mon, CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
228
+ mon->cur_provider = first_active(mon);
229
+ lcb_confmon_stop(mon);
230
+ } else {
231
+ uint32_t interval = 0;
232
+ if (mon->config) {
233
+ /* Not first */
234
+ interval = PROVIDER_SETTING(provider, grace_next_provider);
235
+ }
236
+ lcb_log(LOGARGS(mon, DEBUG), "Will try next provider in %uus", interval);
237
+ mon->state |= CONFMON_S_ITERGRACE;
238
+ lcbio_timer_rearm(mon->as_start, interval);
239
+ }
240
+ }
241
+
242
+ void lcb_confmon_provider_success(clconfig_provider *provider,
243
+ clconfig_info *config)
244
+ {
245
+ do_set_next(provider->parent, config, 1);
246
+ lcb_confmon_stop(provider->parent);
247
+ }
248
+
249
+
250
+ static int do_next_provider(lcb_confmon *mon)
251
+ {
252
+ lcb_list_t *ii;
253
+ mon->state &= ~CONFMON_S_ITERGRACE;
254
+
255
+ LCB_LIST_FOR(ii, (lcb_list_t *)&mon->active_providers) {
256
+ clconfig_info *info;
257
+ clconfig_provider *cached_provider;
258
+
259
+ cached_provider = LCB_LIST_ITEM(ii, clconfig_provider, ll);
260
+ info = cached_provider->get_cached(cached_provider);
261
+ if (!info) {
262
+ continue;
263
+ }
264
+
265
+ if (do_set_next(mon, info, 0)) {
266
+ LOG(mon, DEBUG, "Using cached configuration");
267
+ return 1;
268
+ }
269
+ }
270
+
271
+ lcb_log(LOGARGS(mon, TRACE), "Current provider is %s", provider_string(mon->cur_provider->type));
272
+
273
+ mon->cur_provider->refresh(mon->cur_provider);
274
+ return 0;
275
+ }
276
+
277
+ static void async_start(void *arg)
278
+ {
279
+ do_next_provider(arg);
280
+ }
281
+
282
+ lcb_error_t lcb_confmon_start(lcb_confmon *mon)
283
+ {
284
+ lcb_U32 tmonext = 0;
285
+
286
+ lcbio_async_cancel(mon->as_stop);
287
+ if (IS_REFRESHING(mon)) {
288
+ LOG(mon, DEBUG, "Refresh already in progress...");
289
+ return LCB_SUCCESS;
290
+ }
291
+
292
+ LOG(mon, TRACE, "Start refresh requested");
293
+ lcb_assert(mon->cur_provider);
294
+ mon->state = CONFMON_S_ACTIVE|CONFMON_S_ITERGRACE;
295
+
296
+ if (mon->last_stop_us > 0) {
297
+ lcb_U32 diff = LCB_NS2US(gethrtime()) - mon->last_stop_us;
298
+ if (diff <= mon->settings->grace_next_cycle) {
299
+ tmonext = mon->settings->grace_next_cycle - diff;
300
+ }
301
+ }
302
+
303
+ lcbio_timer_rearm(mon->as_start, tmonext);
304
+ return LCB_SUCCESS;
305
+ }
306
+
307
+ static void async_stop(void *arg)
308
+ {
309
+ lcb_confmon *mon = arg;
310
+ lcb_list_t *ii;
311
+
312
+ LCB_LIST_FOR(ii, (lcb_list_t *)&mon->active_providers) {
313
+ clconfig_provider *provider = LCB_LIST_ITEM(ii, clconfig_provider, ll);
314
+ if (!provider->pause) {
315
+ continue;
316
+ }
317
+ provider->pause(provider);
318
+ }
319
+
320
+ mon->last_stop_us = LCB_NS2US(gethrtime());
321
+ invoke_listeners(mon, CLCONFIG_EVENT_MONITOR_STOPPED, NULL);
322
+ }
323
+
324
+ lcb_error_t lcb_confmon_stop(lcb_confmon *mon)
325
+ {
326
+ if (!IS_REFRESHING(mon)) {
327
+ return LCB_SUCCESS;
328
+ }
329
+ lcbio_timer_disarm(mon->as_start);
330
+ lcbio_async_signal(mon->as_stop);
331
+ mon->state = CONFMON_S_INACTIVE;
332
+ return LCB_SUCCESS;
333
+ }
334
+
335
+ void lcb_clconfig_decref(clconfig_info *info)
336
+ {
337
+ lcb_assert(info->refcount);
338
+
339
+ if (--info->refcount) {
340
+ return;
341
+ }
342
+
343
+ if (info->vbc) {
344
+ lcbvb_destroy(info->vbc);
345
+ }
346
+
347
+ free(info);
348
+ }
349
+
350
+ int lcb_clconfig_compare(const clconfig_info *a, const clconfig_info *b)
351
+ {
352
+ /** First check if both have revisions */
353
+ int rev_a, rev_b;
354
+ rev_a = lcbvb_get_revision(a->vbc);
355
+ rev_b = lcbvb_get_revision(b->vbc);
356
+ if (rev_a >= 0 && rev_b >= 0) {
357
+ return rev_a - rev_b;
358
+ }
359
+
360
+ if (a->cmpclock == b->cmpclock) {
361
+ return 0;
362
+
363
+ } else if (a->cmpclock < b->cmpclock) {
364
+ return -1;
365
+ }
366
+
367
+ return 1;
368
+ }
369
+
370
+ clconfig_info *
371
+ lcb_clconfig_create(lcbvb_CONFIG* config, clconfig_method_t origin)
372
+ {
373
+ clconfig_info *info = calloc(1, sizeof(*info));
374
+ if (!info) {
375
+ return NULL;
376
+ }
377
+ info->refcount = 1;
378
+ info->vbc = config;
379
+ info->origin = origin;
380
+ return info;
381
+ }
382
+
383
+ void lcb_confmon_add_listener(lcb_confmon *mon, clconfig_listener *listener)
384
+ {
385
+ listener->parent = mon;
386
+ lcb_list_append(&mon->listeners, &listener->ll);
387
+ }
388
+
389
+ void lcb_confmon_remove_listener(lcb_confmon *mon, clconfig_listener *listener)
390
+ {
391
+ lcb_list_delete(&listener->ll);
392
+ (void)mon;
393
+ }
394
+
395
+ static void invoke_listeners(lcb_confmon *mon,
396
+ clconfig_event_t event,
397
+ clconfig_info *info)
398
+ {
399
+ lcb_list_t *ll, *ll_next;
400
+ LCB_LIST_SAFE_FOR(ll, ll_next, &mon->listeners) {
401
+ clconfig_listener *lsn = LCB_LIST_ITEM(ll, clconfig_listener, ll);
402
+ lsn->callback(lsn, event, info);
403
+ }
404
+ }
405
+
406
+ static void generic_shutdown(clconfig_provider *provider)
407
+ {
408
+ free(provider);
409
+ }
410
+
411
+ clconfig_provider * lcb_clconfig_create_user(lcb_confmon *mon)
412
+ {
413
+ clconfig_provider *provider = calloc(1, sizeof(*provider));
414
+ provider->type = LCB_CLCONFIG_USER;
415
+ provider->shutdown = generic_shutdown;
416
+
417
+ (void)mon;
418
+ return provider;
419
+ }
420
+
421
+ LCB_INTERNAL_API
422
+ int lcb_confmon_is_refreshing(lcb_confmon *mon)
423
+ {
424
+ return IS_REFRESHING(mon);
425
+ }
426
+
427
+ LCB_INTERNAL_API
428
+ void
429
+ lcb_confmon_set_provider_active(lcb_confmon *mon,
430
+ clconfig_method_t type, int enabled)
431
+ {
432
+ clconfig_provider *provider = mon->all_providers[type];
433
+ if (provider->enabled == enabled) {
434
+ return;
435
+ } else {
436
+ provider->enabled = enabled;
437
+ }
438
+ lcb_confmon_prepare(mon);
439
+ }
440
+
441
+ void
442
+ lcb_confmon_dump(lcb_confmon *mon, FILE *fp)
443
+ {
444
+ unsigned ii;
445
+ fprintf(fp, "CONFMON=%p\n", (void*)mon);
446
+ fprintf(fp, "STATE= (0x%x)", mon->state);
447
+ if (mon->state & CONFMON_S_ACTIVE) {
448
+ fprintf(fp, "ACTIVE|");
449
+ }
450
+ if (mon->state == CONFMON_S_INACTIVE) {
451
+ fprintf(fp, "INACTIVE/IDLE");
452
+ }
453
+ if (mon->state & CONFMON_S_ITERGRACE) {
454
+ fprintf(fp, "ITERGRACE");
455
+ }
456
+ fprintf(fp, "\n");
457
+ fprintf(fp, "LAST ERROR: 0x%x\n", mon->last_error);
458
+
459
+
460
+ for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
461
+ clconfig_provider *cur = mon->all_providers[ii];
462
+ if (!cur) {
463
+ continue;
464
+ }
465
+
466
+ fprintf(fp, "** PROVIDER: 0x%x (%s) %p\n", cur->type, provider_string(cur->type), (void*)cur);
467
+ fprintf(fp, "** ENABLED: %s\n", cur->enabled ? "YES" : "NO");
468
+ fprintf(fp, "** CURRENT: %s\n", cur == mon->cur_provider ? "YES" : "NO");
469
+ if (cur->dump) {
470
+ cur->dump(cur, fp);
471
+ }
472
+ fprintf(fp, "\n");
473
+ }
474
+ }