grpc 0.13.0 → 0.13.1.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/Makefile +1114 -937
- data/include/grpc/census.h +71 -89
- data/include/grpc/compression.h +7 -7
- data/include/grpc/grpc.h +65 -68
- data/include/grpc/grpc_security.h +38 -38
- data/include/grpc/impl/codegen/alloc.h +7 -7
- data/include/grpc/impl/codegen/byte_buffer.h +13 -13
- data/include/grpc/impl/codegen/grpc_types.h +7 -2
- data/include/grpc/impl/codegen/log.h +5 -5
- data/include/grpc/impl/codegen/port_platform.h +14 -6
- data/include/grpc/impl/codegen/slice.h +15 -15
- data/include/grpc/impl/codegen/slice_buffer.h +17 -17
- data/include/grpc/impl/codegen/sync.h +26 -22
- data/include/grpc/impl/codegen/time.h +22 -24
- data/include/grpc/support/avl.h +9 -8
- data/include/grpc/support/cmdline.h +12 -12
- data/include/grpc/support/cpu.h +2 -2
- data/include/grpc/support/histogram.h +22 -22
- data/include/grpc/support/host_port.h +2 -2
- data/include/grpc/support/log_win32.h +1 -1
- data/include/grpc/support/string_util.h +2 -2
- data/include/grpc/support/subprocess.h +5 -5
- data/include/grpc/support/thd.h +9 -9
- data/include/grpc/support/useful.h +3 -1
- data/src/core/census/context.c +64 -85
- data/src/core/census/grpc_filter.c +2 -2
- data/src/core/census/mlog.c +600 -0
- data/src/core/census/mlog.h +95 -0
- data/src/core/channel/channel_args.c +67 -6
- data/src/core/channel/channel_args.h +7 -1
- data/src/core/channel/client_channel.c +26 -36
- data/src/core/channel/client_uchannel.c +1 -1
- data/src/core/channel/http_client_filter.c +2 -2
- data/src/core/channel/http_server_filter.c +2 -2
- data/src/core/channel/subchannel_call_holder.c +5 -7
- data/src/core/client_config/connector.c +3 -2
- data/src/core/client_config/connector.h +2 -2
- data/src/core/client_config/lb_policies/load_balancer_api.c +163 -0
- data/src/core/client_config/lb_policies/load_balancer_api.h +85 -0
- data/src/core/client_config/lb_policies/pick_first.c +10 -11
- data/src/core/client_config/lb_policies/round_robin.c +7 -8
- data/src/core/client_config/lb_policy.c +3 -3
- data/src/core/client_config/lb_policy.h +3 -2
- data/src/core/client_config/subchannel.c +51 -21
- data/src/core/client_config/subchannel.h +15 -6
- data/src/core/client_config/subchannel_index.c +261 -0
- data/src/core/client_config/subchannel_index.h +77 -0
- data/src/core/compression/{algorithm.c → compression_algorithm.c} +0 -0
- data/src/core/httpcli/httpcli.c +13 -11
- data/src/core/httpcli/httpcli.h +3 -2
- data/src/core/httpcli/httpcli_security_connector.c +7 -7
- data/src/core/iomgr/fd_posix.c +4 -2
- data/src/core/iomgr/iocp_windows.c +10 -6
- data/src/core/iomgr/iocp_windows.h +9 -2
- data/src/core/iomgr/iomgr.c +18 -2
- data/src/core/iomgr/iomgr_internal.h +5 -1
- data/src/core/iomgr/pollset.h +9 -10
- data/src/core/iomgr/pollset_multipoller_with_epoll.c +1 -0
- data/src/core/iomgr/pollset_multipoller_with_poll_posix.c +10 -5
- data/src/core/iomgr/pollset_posix.c +30 -35
- data/src/core/iomgr/pollset_posix.h +10 -6
- data/src/core/iomgr/pollset_set.h +3 -9
- data/src/core/iomgr/pollset_set_posix.c +23 -3
- data/src/core/iomgr/pollset_set_posix.h +2 -18
- data/src/core/iomgr/pollset_set_windows.c +3 -3
- data/src/core/iomgr/pollset_set_windows.h +2 -2
- data/src/core/iomgr/pollset_windows.c +24 -21
- data/src/core/iomgr/pollset_windows.h +1 -5
- data/src/core/iomgr/tcp_client_posix.c +7 -5
- data/src/core/iomgr/tcp_posix.c +4 -2
- data/src/core/iomgr/tcp_server_windows.c +1 -2
- data/src/core/iomgr/timer.c +2 -3
- data/src/core/iomgr/timer.h +21 -1
- data/src/core/iomgr/timer_heap.c +10 -12
- data/src/core/iomgr/udp_server.c +5 -4
- data/src/core/iomgr/udp_server.h +1 -0
- data/src/core/iomgr/workqueue_posix.c +1 -0
- data/src/core/iomgr/workqueue_posix.h +3 -1
- data/src/core/proto/grpc/lb/v0/load_balancer.pb.c +119 -0
- data/src/core/proto/grpc/lb/v0/load_balancer.pb.h +182 -0
- data/src/core/security/{base64.c → b64.c} +1 -1
- data/src/core/security/{base64.h → b64.h} +1 -1
- data/src/core/security/client_auth_filter.c +0 -1
- data/src/core/security/credentials.c +12 -5
- data/src/core/security/credentials.h +3 -3
- data/src/core/security/google_default_credentials.c +24 -19
- data/src/core/security/handshake.c +15 -7
- data/src/core/security/handshake.h +2 -1
- data/src/core/security/json_token.c +1 -1
- data/src/core/security/jwt_verifier.c +1 -1
- data/src/core/security/security_connector.c +84 -64
- data/src/core/security/security_connector.h +42 -22
- data/src/core/security/security_context.c +8 -3
- data/src/core/security/server_auth_filter.c +2 -2
- data/src/core/security/server_secure_chttp2.c +7 -7
- data/src/core/support/avl.c +2 -2
- data/src/core/support/env_linux.c +17 -0
- data/src/core/support/{file.c → load_file.c} +2 -2
- data/src/core/support/{file.h → load_file.h} +4 -12
- data/src/core/support/sync.c +6 -1
- data/src/core/support/time_posix.c +1 -1
- data/src/core/{iomgr/timer_internal.h → support/tmpfile.h} +17 -23
- data/src/core/support/{file_posix.c → tmpfile_posix.c} +2 -2
- data/src/core/support/{file_win32.c → tmpfile_win32.c} +2 -2
- data/src/core/surface/alarm.c +3 -2
- data/src/core/surface/call.c +102 -52
- data/src/core/surface/channel_create.c +1 -1
- data/src/core/surface/completion_queue.c +73 -41
- data/src/core/surface/init.c +4 -0
- data/src/core/surface/lame_client.c +1 -2
- data/src/core/surface/secure_channel_create.c +6 -7
- data/src/core/surface/server.c +13 -5
- data/src/core/surface/validate_metadata.c +1 -1
- data/src/core/surface/version.c +1 -1
- data/src/core/transport/chttp2/internal.h +22 -10
- data/src/core/transport/chttp2/parsing.c +3 -3
- data/src/core/transport/chttp2/stream_lists.c +39 -21
- data/src/core/transport/chttp2/writing.c +19 -28
- data/src/core/transport/chttp2_transport.c +80 -37
- data/src/core/transport/metadata.c +8 -0
- data/src/core/transport/static_metadata.c +17 -17
- data/src/core/transport/static_metadata.h +3 -3
- data/src/core/transport/transport.c +2 -1
- data/src/core/transport/transport.h +12 -5
- data/src/ruby/ext/grpc/extconf.rb +1 -0
- data/src/ruby/ext/grpc/rb_call.c +6 -0
- data/src/ruby/ext/grpc/rb_call_credentials.c +12 -14
- data/src/ruby/ext/grpc/rb_channel.c +8 -14
- data/src/ruby/ext/grpc/rb_channel_credentials.c +11 -12
- data/src/ruby/ext/grpc/rb_grpc.c +19 -18
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +8 -2
- data/src/ruby/lib/grpc/core/time_consts.rb +2 -2
- data/src/ruby/lib/grpc/errors.rb +2 -2
- data/src/ruby/lib/grpc/generic/rpc_server.rb +58 -39
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/README.md +2 -2
- data/src/ruby/pb/generate_proto_ruby.sh +2 -2
- data/src/ruby/pb/grpc/health/checker.rb +11 -11
- data/src/ruby/pb/grpc/health/v1/health.rb +28 -0
- data/src/ruby/pb/grpc/health/{v1alpha → v1}/health_services.rb +4 -4
- data/src/ruby/spec/client_server_spec.rb +2 -1
- data/src/ruby/spec/generic/rpc_server_spec.rb +3 -22
- data/src/ruby/spec/pb/health/checker_spec.rb +22 -36
- data/third_party/nanopb/pb.h +547 -0
- data/third_party/nanopb/pb_common.c +97 -0
- data/third_party/nanopb/pb_common.h +42 -0
- data/third_party/nanopb/pb_decode.c +1319 -0
- data/third_party/nanopb/pb_decode.h +149 -0
- data/third_party/nanopb/pb_encode.c +690 -0
- data/third_party/nanopb/pb_encode.h +154 -0
- metadata +32 -16
- data/src/ruby/pb/grpc/health/v1alpha/health.rb +0 -29
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
*
|
3
|
-
* Copyright 2015, Google Inc.
|
3
|
+
* Copyright 2015-2016, Google Inc.
|
4
4
|
* All rights reserved.
|
5
5
|
*
|
6
6
|
* Redistribution and use in source and binary forms, with or without
|
@@ -48,7 +48,8 @@ typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel,
|
|
48
48
|
struct grpc_lb_policy {
|
49
49
|
const grpc_lb_policy_vtable *vtable;
|
50
50
|
gpr_atm ref_pair;
|
51
|
-
|
51
|
+
/* owned pointer to interested parties in load balancing decisions */
|
52
|
+
grpc_pollset_set *interested_parties;
|
52
53
|
};
|
53
54
|
|
54
55
|
struct grpc_lb_policy_vtable {
|
@@ -36,16 +36,17 @@
|
|
36
36
|
#include <string.h>
|
37
37
|
|
38
38
|
#include <grpc/support/alloc.h>
|
39
|
+
#include <grpc/support/avl.h>
|
39
40
|
|
40
41
|
#include "src/core/channel/channel_args.h"
|
41
42
|
#include "src/core/channel/client_channel.h"
|
42
43
|
#include "src/core/channel/connected_channel.h"
|
43
44
|
#include "src/core/client_config/initial_connect_string.h"
|
45
|
+
#include "src/core/client_config/subchannel_index.h"
|
44
46
|
#include "src/core/iomgr/timer.h"
|
45
47
|
#include "src/core/profiling/timers.h"
|
46
48
|
#include "src/core/surface/channel.h"
|
47
49
|
#include "src/core/transport/connectivity_state.h"
|
48
|
-
#include "src/core/transport/connectivity_state.h"
|
49
50
|
|
50
51
|
#define INTERNAL_REF_BITS 16
|
51
52
|
#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
|
@@ -94,6 +95,8 @@ struct grpc_subchannel {
|
|
94
95
|
struct sockaddr *addr;
|
95
96
|
size_t addr_len;
|
96
97
|
|
98
|
+
grpc_subchannel_key *key;
|
99
|
+
|
97
100
|
/** initial string to send to peer */
|
98
101
|
gpr_slice initial_connect_string;
|
99
102
|
|
@@ -105,7 +108,7 @@ struct grpc_subchannel {
|
|
105
108
|
|
106
109
|
/** pollset_set tracking who's interested in a connection
|
107
110
|
being setup */
|
108
|
-
grpc_pollset_set pollset_set;
|
111
|
+
grpc_pollset_set *pollset_set;
|
109
112
|
|
110
113
|
/** active connection, or null; of type grpc_connected_subchannel */
|
111
114
|
gpr_atm connected_subchannel;
|
@@ -206,7 +209,8 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
|
|
206
209
|
gpr_slice_unref(c->initial_connect_string);
|
207
210
|
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
|
208
211
|
grpc_connector_unref(exec_ctx, c->connector);
|
209
|
-
grpc_pollset_set_destroy(
|
212
|
+
grpc_pollset_set_destroy(c->pollset_set);
|
213
|
+
grpc_subchannel_key_destroy(exec_ctx, c->key);
|
210
214
|
gpr_free(c);
|
211
215
|
}
|
212
216
|
|
@@ -222,22 +226,42 @@ static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta,
|
|
222
226
|
return old_val;
|
223
227
|
}
|
224
228
|
|
225
|
-
|
229
|
+
grpc_subchannel *grpc_subchannel_ref(grpc_subchannel *c
|
230
|
+
GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
226
231
|
gpr_atm old_refs;
|
227
232
|
old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS),
|
228
233
|
0 REF_MUTATE_PURPOSE("STRONG_REF"));
|
229
234
|
GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0);
|
235
|
+
return c;
|
230
236
|
}
|
231
237
|
|
232
|
-
|
233
|
-
|
238
|
+
grpc_subchannel *grpc_subchannel_weak_ref(grpc_subchannel *c
|
239
|
+
GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
234
240
|
gpr_atm old_refs;
|
235
241
|
old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF"));
|
236
242
|
GPR_ASSERT(old_refs != 0);
|
243
|
+
return c;
|
244
|
+
}
|
245
|
+
|
246
|
+
grpc_subchannel *grpc_subchannel_ref_from_weak_ref(
|
247
|
+
grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
248
|
+
if (!c) return NULL;
|
249
|
+
for (;;) {
|
250
|
+
gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair);
|
251
|
+
if (old_refs >= (1 << INTERNAL_REF_BITS)) {
|
252
|
+
gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS);
|
253
|
+
if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) {
|
254
|
+
return c;
|
255
|
+
}
|
256
|
+
} else {
|
257
|
+
return NULL;
|
258
|
+
}
|
259
|
+
}
|
237
260
|
}
|
238
261
|
|
239
262
|
static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
|
240
263
|
grpc_connected_subchannel *con;
|
264
|
+
grpc_subchannel_index_unregister(exec_ctx, c->key, c);
|
241
265
|
gpr_mu_lock(&c->mu);
|
242
266
|
GPR_ASSERT(!c->disconnected);
|
243
267
|
c->disconnected = 1;
|
@@ -276,10 +300,19 @@ static uint32_t random_seed() {
|
|
276
300
|
return (uint32_t)(gpr_time_to_millis(gpr_now(GPR_CLOCK_MONOTONIC)));
|
277
301
|
}
|
278
302
|
|
279
|
-
grpc_subchannel *grpc_subchannel_create(
|
303
|
+
grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
|
304
|
+
grpc_connector *connector,
|
280
305
|
grpc_subchannel_args *args) {
|
281
|
-
|
306
|
+
grpc_subchannel_key *key = grpc_subchannel_key_create(connector, args);
|
307
|
+
grpc_subchannel *c = grpc_subchannel_index_find(exec_ctx, key);
|
308
|
+
if (c) {
|
309
|
+
grpc_subchannel_key_destroy(exec_ctx, key);
|
310
|
+
return c;
|
311
|
+
}
|
312
|
+
|
313
|
+
c = gpr_malloc(sizeof(*c));
|
282
314
|
memset(c, 0, sizeof(*c));
|
315
|
+
c->key = key;
|
283
316
|
gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS);
|
284
317
|
c->connector = connector;
|
285
318
|
grpc_connector_ref(c->connector);
|
@@ -293,7 +326,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
|
|
293
326
|
}
|
294
327
|
c->addr = gpr_malloc(args->addr_len);
|
295
328
|
memcpy(c->addr, args->addr, args->addr_len);
|
296
|
-
|
329
|
+
c->pollset_set = grpc_pollset_set_create();
|
297
330
|
c->addr_len = args->addr_len;
|
298
331
|
grpc_set_initial_connect_string(&c->addr, &c->addr_len,
|
299
332
|
&c->initial_connect_string);
|
@@ -305,13 +338,14 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
|
|
305
338
|
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
|
306
339
|
"subchannel");
|
307
340
|
gpr_mu_init(&c->mu);
|
308
|
-
|
341
|
+
|
342
|
+
return grpc_subchannel_index_register(exec_ctx, key, c);
|
309
343
|
}
|
310
344
|
|
311
345
|
static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
|
312
346
|
grpc_connect_in_args args;
|
313
347
|
|
314
|
-
args.interested_parties =
|
348
|
+
args.interested_parties = c->pollset_set;
|
315
349
|
args.addr = c->addr;
|
316
350
|
args.addr_len = c->addr_len;
|
317
351
|
args.deadline = compute_connect_deadline(c);
|
@@ -345,7 +379,7 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
345
379
|
external_state_watcher *w = arg;
|
346
380
|
grpc_closure *follow_up = w->notify;
|
347
381
|
if (w->pollset_set != NULL) {
|
348
|
-
grpc_pollset_set_del_pollset_set(exec_ctx,
|
382
|
+
grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set,
|
349
383
|
w->pollset_set);
|
350
384
|
}
|
351
385
|
gpr_mu_lock(&w->subchannel->mu);
|
@@ -361,7 +395,6 @@ void grpc_subchannel_notify_on_state_change(
|
|
361
395
|
grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
|
362
396
|
grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
|
363
397
|
grpc_closure *notify) {
|
364
|
-
int do_connect = 0;
|
365
398
|
external_state_watcher *w;
|
366
399
|
|
367
400
|
if (state == NULL) {
|
@@ -381,7 +414,7 @@ void grpc_subchannel_notify_on_state_change(
|
|
381
414
|
w->notify = notify;
|
382
415
|
grpc_closure_init(&w->closure, on_external_state_watcher_done, w);
|
383
416
|
if (interested_parties != NULL) {
|
384
|
-
grpc_pollset_set_add_pollset_set(exec_ctx,
|
417
|
+
grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
|
385
418
|
interested_parties);
|
386
419
|
}
|
387
420
|
GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher");
|
@@ -391,17 +424,13 @@ void grpc_subchannel_notify_on_state_change(
|
|
391
424
|
w->next->prev = w->prev->next = w;
|
392
425
|
if (grpc_connectivity_state_notify_on_state_change(
|
393
426
|
exec_ctx, &c->state_tracker, state, &w->closure)) {
|
394
|
-
do_connect = 1;
|
395
427
|
c->connecting = 1;
|
396
428
|
/* released by connection */
|
397
429
|
GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
|
430
|
+
start_connect(exec_ctx, c);
|
398
431
|
}
|
399
432
|
gpr_mu_unlock(&c->mu);
|
400
433
|
}
|
401
|
-
|
402
|
-
if (do_connect) {
|
403
|
-
start_connect(exec_ctx, c);
|
404
|
-
}
|
405
434
|
}
|
406
435
|
|
407
436
|
void grpc_connected_subchannel_process_transport_op(
|
@@ -539,7 +568,7 @@ static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
|
|
539
568
|
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
|
540
569
|
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
|
541
570
|
grpc_connected_subchannel_notify_on_state_change(
|
542
|
-
exec_ctx, con,
|
571
|
+
exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state,
|
543
572
|
&sw_subchannel->closure);
|
544
573
|
|
545
574
|
/* signal completion */
|
@@ -601,11 +630,12 @@ static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool iomgr_success) {
|
|
601
630
|
if (c->disconnected) {
|
602
631
|
iomgr_success = 0;
|
603
632
|
}
|
604
|
-
gpr_mu_unlock(&c->mu);
|
605
633
|
if (iomgr_success) {
|
606
634
|
update_reconnect_parameters(c);
|
607
635
|
continue_connect(exec_ctx, c);
|
636
|
+
gpr_mu_unlock(&c->mu);
|
608
637
|
} else {
|
638
|
+
gpr_mu_unlock(&c->mu);
|
609
639
|
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
|
610
640
|
}
|
611
641
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
*
|
3
|
-
* Copyright 2015, Google Inc.
|
3
|
+
* Copyright 2015-2016, Google Inc.
|
4
4
|
* All rights reserved.
|
5
5
|
*
|
6
6
|
* Redistribution and use in source and binary forms, with or without
|
@@ -48,6 +48,8 @@ typedef struct grpc_subchannel_args grpc_subchannel_args;
|
|
48
48
|
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
|
49
49
|
#define GRPC_SUBCHANNEL_REF(p, r) \
|
50
50
|
grpc_subchannel_ref((p), __FILE__, __LINE__, (r))
|
51
|
+
#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \
|
52
|
+
grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r))
|
51
53
|
#define GRPC_SUBCHANNEL_UNREF(cl, p, r) \
|
52
54
|
grpc_subchannel_unref((cl), (p), __FILE__, __LINE__, (r))
|
53
55
|
#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \
|
@@ -66,6 +68,8 @@ typedef struct grpc_subchannel_args grpc_subchannel_args;
|
|
66
68
|
, const char *file, int line, const char *reason
|
67
69
|
#else
|
68
70
|
#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p))
|
71
|
+
#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \
|
72
|
+
grpc_subchannel_ref_from_weak_ref((p))
|
69
73
|
#define GRPC_SUBCHANNEL_UNREF(cl, p, r) grpc_subchannel_unref((cl), (p))
|
70
74
|
#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p))
|
71
75
|
#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \
|
@@ -79,13 +83,15 @@ typedef struct grpc_subchannel_args grpc_subchannel_args;
|
|
79
83
|
#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS
|
80
84
|
#endif
|
81
85
|
|
82
|
-
|
83
|
-
|
86
|
+
grpc_subchannel *grpc_subchannel_ref(grpc_subchannel *channel
|
87
|
+
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
|
88
|
+
grpc_subchannel *grpc_subchannel_ref_from_weak_ref(
|
89
|
+
grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
|
84
90
|
void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx,
|
85
91
|
grpc_subchannel *channel
|
86
92
|
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
|
87
|
-
|
88
|
-
|
93
|
+
grpc_subchannel *grpc_subchannel_weak_ref(grpc_subchannel *channel
|
94
|
+
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
|
89
95
|
void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx,
|
90
96
|
grpc_subchannel *channel
|
91
97
|
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
|
@@ -146,6 +152,8 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
|
|
146
152
|
grpc_subchannel_call *subchannel_call);
|
147
153
|
|
148
154
|
struct grpc_subchannel_args {
|
155
|
+
/* When updating this struct, also update subchannel_index.c */
|
156
|
+
|
149
157
|
/** Channel filters for this channel - wrapped factories will likely
|
150
158
|
want to mutate this */
|
151
159
|
const grpc_channel_filter **filters;
|
@@ -159,7 +167,8 @@ struct grpc_subchannel_args {
|
|
159
167
|
};
|
160
168
|
|
161
169
|
/** create a subchannel given a connector */
|
162
|
-
grpc_subchannel *grpc_subchannel_create(
|
170
|
+
grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
|
171
|
+
grpc_connector *connector,
|
163
172
|
grpc_subchannel_args *args);
|
164
173
|
|
165
174
|
#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H */
|
@@ -0,0 +1,261 @@
|
|
1
|
+
//
|
2
|
+
//
|
3
|
+
// Copyright 2016, Google Inc.
|
4
|
+
// All rights reserved.
|
5
|
+
//
|
6
|
+
// Redistribution and use in source and binary forms, with or without
|
7
|
+
// modification, are permitted provided that the following conditions are
|
8
|
+
// met:
|
9
|
+
//
|
10
|
+
// * Redistributions of source code must retain the above copyright
|
11
|
+
// notice, this list of conditions and the following disclaimer.
|
12
|
+
// * Redistributions in binary form must reproduce the above
|
13
|
+
// copyright notice, this list of conditions and the following disclaimer
|
14
|
+
// in the documentation and/or other materials provided with the
|
15
|
+
// distribution.
|
16
|
+
// * Neither the name of Google Inc. nor the names of its
|
17
|
+
// contributors may be used to endorse or promote products derived from
|
18
|
+
// this software without specific prior written permission.
|
19
|
+
//
|
20
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
//
|
32
|
+
//
|
33
|
+
|
34
|
+
#include "src/core/client_config/subchannel_index.h"
|
35
|
+
|
36
|
+
#include <stdbool.h>
|
37
|
+
#include <string.h>
|
38
|
+
|
39
|
+
#include <grpc/support/alloc.h>
|
40
|
+
#include <grpc/support/avl.h>
|
41
|
+
#include <grpc/support/tls.h>
|
42
|
+
|
43
|
+
#include "src/core/channel/channel_args.h"
|
44
|
+
|
45
|
+
// a map of subchannel_key --> subchannel, used for detecting connections
|
46
|
+
// to the same destination in order to share them
|
47
|
+
static gpr_avl g_subchannel_index;
|
48
|
+
|
49
|
+
static gpr_mu g_mu;
|
50
|
+
|
51
|
+
struct grpc_subchannel_key {
|
52
|
+
grpc_connector *connector;
|
53
|
+
grpc_subchannel_args args;
|
54
|
+
};
|
55
|
+
|
56
|
+
GPR_TLS_DECL(subchannel_index_exec_ctx);
|
57
|
+
|
58
|
+
static void enter_ctx(grpc_exec_ctx *exec_ctx) {
|
59
|
+
GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == 0);
|
60
|
+
gpr_tls_set(&subchannel_index_exec_ctx, (intptr_t)exec_ctx);
|
61
|
+
}
|
62
|
+
|
63
|
+
static void leave_ctx(grpc_exec_ctx *exec_ctx) {
|
64
|
+
GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == (intptr_t)exec_ctx);
|
65
|
+
gpr_tls_set(&subchannel_index_exec_ctx, 0);
|
66
|
+
}
|
67
|
+
|
68
|
+
static grpc_exec_ctx *current_ctx() {
|
69
|
+
grpc_exec_ctx *c = (grpc_exec_ctx *)gpr_tls_get(&subchannel_index_exec_ctx);
|
70
|
+
GPR_ASSERT(c != NULL);
|
71
|
+
return c;
|
72
|
+
}
|
73
|
+
|
74
|
+
static grpc_subchannel_key *create_key(
|
75
|
+
grpc_connector *connector, grpc_subchannel_args *args,
|
76
|
+
grpc_channel_args *(*copy_channel_args)(const grpc_channel_args *args)) {
|
77
|
+
grpc_subchannel_key *k = gpr_malloc(sizeof(*k));
|
78
|
+
k->connector = grpc_connector_ref(connector);
|
79
|
+
k->args.filter_count = args->filter_count;
|
80
|
+
k->args.filters = gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count);
|
81
|
+
memcpy((grpc_channel_filter *)k->args.filters, args->filters,
|
82
|
+
sizeof(*k->args.filters) * k->args.filter_count);
|
83
|
+
k->args.addr_len = args->addr_len;
|
84
|
+
k->args.addr = gpr_malloc(args->addr_len);
|
85
|
+
memcpy(k->args.addr, args->addr, k->args.addr_len);
|
86
|
+
k->args.args = copy_channel_args(args->args);
|
87
|
+
return k;
|
88
|
+
}
|
89
|
+
|
90
|
+
grpc_subchannel_key *grpc_subchannel_key_create(grpc_connector *connector,
|
91
|
+
grpc_subchannel_args *args) {
|
92
|
+
return create_key(connector, args, grpc_channel_args_normalize);
|
93
|
+
}
|
94
|
+
|
95
|
+
static grpc_subchannel_key *subchannel_key_copy(grpc_subchannel_key *k) {
|
96
|
+
return create_key(k->connector, &k->args, grpc_channel_args_copy);
|
97
|
+
}
|
98
|
+
|
99
|
+
static int subchannel_key_compare(grpc_subchannel_key *a,
|
100
|
+
grpc_subchannel_key *b) {
|
101
|
+
int c = GPR_ICMP(a->connector, b->connector);
|
102
|
+
if (c != 0) return c;
|
103
|
+
c = GPR_ICMP(a->args.addr_len, b->args.addr_len);
|
104
|
+
if (c != 0) return c;
|
105
|
+
c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
|
106
|
+
if (c != 0) return c;
|
107
|
+
c = memcmp(a->args.addr, b->args.addr, a->args.addr_len);
|
108
|
+
if (c != 0) return c;
|
109
|
+
c = memcmp(a->args.filters, b->args.filters,
|
110
|
+
a->args.filter_count * sizeof(*a->args.filters));
|
111
|
+
return grpc_channel_args_compare(a->args.args, b->args.args);
|
112
|
+
}
|
113
|
+
|
114
|
+
void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
|
115
|
+
grpc_subchannel_key *k) {
|
116
|
+
grpc_connector_unref(exec_ctx, k->connector);
|
117
|
+
gpr_free(k->args.addr);
|
118
|
+
gpr_free((grpc_channel_args *)k->args.filters);
|
119
|
+
grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
|
120
|
+
gpr_free(k);
|
121
|
+
}
|
122
|
+
|
123
|
+
static void sck_avl_destroy(void *p) {
|
124
|
+
grpc_subchannel_key_destroy(current_ctx(), p);
|
125
|
+
}
|
126
|
+
|
127
|
+
static void *sck_avl_copy(void *p) { return subchannel_key_copy(p); }
|
128
|
+
|
129
|
+
static long sck_avl_compare(void *a, void *b) {
|
130
|
+
return subchannel_key_compare(a, b);
|
131
|
+
}
|
132
|
+
|
133
|
+
static void scv_avl_destroy(void *p) {
|
134
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(current_ctx(), p, "subchannel_index");
|
135
|
+
}
|
136
|
+
|
137
|
+
static void *scv_avl_copy(void *p) {
|
138
|
+
GRPC_SUBCHANNEL_WEAK_REF(p, "subchannel_index");
|
139
|
+
return p;
|
140
|
+
}
|
141
|
+
|
142
|
+
static const gpr_avl_vtable subchannel_avl_vtable = {
|
143
|
+
.destroy_key = sck_avl_destroy,
|
144
|
+
.copy_key = sck_avl_copy,
|
145
|
+
.compare_keys = sck_avl_compare,
|
146
|
+
.destroy_value = scv_avl_destroy,
|
147
|
+
.copy_value = scv_avl_copy};
|
148
|
+
|
149
|
+
void grpc_subchannel_index_init(void) {
|
150
|
+
g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable);
|
151
|
+
gpr_mu_init(&g_mu);
|
152
|
+
gpr_tls_init(&subchannel_index_exec_ctx);
|
153
|
+
}
|
154
|
+
|
155
|
+
void grpc_subchannel_index_shutdown(void) {
|
156
|
+
gpr_mu_destroy(&g_mu);
|
157
|
+
gpr_avl_unref(g_subchannel_index);
|
158
|
+
gpr_tls_destroy(&subchannel_index_exec_ctx);
|
159
|
+
}
|
160
|
+
|
161
|
+
grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx,
|
162
|
+
grpc_subchannel_key *key) {
|
163
|
+
enter_ctx(exec_ctx);
|
164
|
+
|
165
|
+
// Lock, and take a reference to the subchannel index.
|
166
|
+
// We don't need to do the search under a lock as avl's are immutable.
|
167
|
+
gpr_mu_lock(&g_mu);
|
168
|
+
gpr_avl index = gpr_avl_ref(g_subchannel_index);
|
169
|
+
gpr_mu_unlock(&g_mu);
|
170
|
+
|
171
|
+
grpc_subchannel *c =
|
172
|
+
GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(gpr_avl_get(index, key), "index_find");
|
173
|
+
gpr_avl_unref(index);
|
174
|
+
|
175
|
+
leave_ctx(exec_ctx);
|
176
|
+
return c;
|
177
|
+
}
|
178
|
+
|
179
|
+
grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx,
|
180
|
+
grpc_subchannel_key *key,
|
181
|
+
grpc_subchannel *constructed) {
|
182
|
+
enter_ctx(exec_ctx);
|
183
|
+
|
184
|
+
grpc_subchannel *c = NULL;
|
185
|
+
|
186
|
+
while (c == NULL) {
|
187
|
+
// Compare and swap loop:
|
188
|
+
// - take a reference to the current index
|
189
|
+
gpr_mu_lock(&g_mu);
|
190
|
+
gpr_avl index = gpr_avl_ref(g_subchannel_index);
|
191
|
+
gpr_mu_unlock(&g_mu);
|
192
|
+
|
193
|
+
// - Check to see if a subchannel already exists
|
194
|
+
c = gpr_avl_get(index, key);
|
195
|
+
if (c != NULL) {
|
196
|
+
// yes -> we're done
|
197
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, constructed, "index_register");
|
198
|
+
} else {
|
199
|
+
// no -> update the avl and compare/swap
|
200
|
+
gpr_avl updated =
|
201
|
+
gpr_avl_add(gpr_avl_ref(index), subchannel_key_copy(key),
|
202
|
+
GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"));
|
203
|
+
|
204
|
+
// it may happen (but it's expected to be unlikely)
|
205
|
+
// that some other thread has changed the index:
|
206
|
+
// compare/swap here to check that, and retry as necessary
|
207
|
+
gpr_mu_lock(&g_mu);
|
208
|
+
if (index.root == g_subchannel_index.root) {
|
209
|
+
GPR_SWAP(gpr_avl, updated, g_subchannel_index);
|
210
|
+
c = constructed;
|
211
|
+
}
|
212
|
+
gpr_mu_unlock(&g_mu);
|
213
|
+
|
214
|
+
gpr_avl_unref(updated);
|
215
|
+
}
|
216
|
+
gpr_avl_unref(index);
|
217
|
+
}
|
218
|
+
|
219
|
+
leave_ctx(exec_ctx);
|
220
|
+
|
221
|
+
return c;
|
222
|
+
}
|
223
|
+
|
224
|
+
void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx,
|
225
|
+
grpc_subchannel_key *key,
|
226
|
+
grpc_subchannel *constructed) {
|
227
|
+
enter_ctx(exec_ctx);
|
228
|
+
|
229
|
+
bool done = false;
|
230
|
+
while (!done) {
|
231
|
+
// Compare and swap loop:
|
232
|
+
// - take a reference to the current index
|
233
|
+
gpr_mu_lock(&g_mu);
|
234
|
+
gpr_avl index = gpr_avl_ref(g_subchannel_index);
|
235
|
+
gpr_mu_unlock(&g_mu);
|
236
|
+
|
237
|
+
// Check to see if this key still refers to the previously
|
238
|
+
// registered subchannel
|
239
|
+
grpc_subchannel *c = gpr_avl_get(index, key);
|
240
|
+
if (c != constructed) {
|
241
|
+
gpr_avl_unref(index);
|
242
|
+
break;
|
243
|
+
}
|
244
|
+
|
245
|
+
// compare and swap the update (some other thread may have
|
246
|
+
// mutated the index behind us)
|
247
|
+
gpr_avl updated = gpr_avl_remove(gpr_avl_ref(index), key);
|
248
|
+
|
249
|
+
gpr_mu_lock(&g_mu);
|
250
|
+
if (index.root == g_subchannel_index.root) {
|
251
|
+
GPR_SWAP(gpr_avl, updated, g_subchannel_index);
|
252
|
+
done = true;
|
253
|
+
}
|
254
|
+
gpr_mu_unlock(&g_mu);
|
255
|
+
|
256
|
+
gpr_avl_unref(updated);
|
257
|
+
gpr_avl_unref(index);
|
258
|
+
}
|
259
|
+
|
260
|
+
leave_ctx(exec_ctx);
|
261
|
+
}
|