diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/ext/filters/client_channel/retry_throttle.c | 22 | ||||
-rw-r--r-- | src/core/ext/filters/client_channel/subchannel_index.c | 87 | ||||
-rw-r--r-- | src/core/lib/support/avl.c | 177 |
3 files changed, 145 insertions, 141 deletions
diff --git a/src/core/ext/filters/client_channel/retry_throttle.c b/src/core/ext/filters/client_channel/retry_throttle.c index 3009e21d49..0c7a3ae651 100644 --- a/src/core/ext/filters/client_channel/retry_throttle.c +++ b/src/core/ext/filters/client_channel/retry_throttle.c @@ -130,24 +130,28 @@ static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create( // avl vtable for string -> server_retry_throttle_data map // -static void* copy_server_name(void* key) { return gpr_strdup(key); } +static void* copy_server_name(void* key, void* unused) { + return gpr_strdup(key); +} -static long compare_server_name(void* key1, void* key2) { +static long compare_server_name(void* key1, void* key2, void* unused) { return strcmp(key1, key2); } -static void destroy_server_retry_throttle_data(void* value) { +static void destroy_server_retry_throttle_data(void* value, void* unused) { grpc_server_retry_throttle_data* throttle_data = value; grpc_server_retry_throttle_data_unref(throttle_data); } -static void* copy_server_retry_throttle_data(void* value) { +static void* copy_server_retry_throttle_data(void* value, void* unused) { grpc_server_retry_throttle_data* throttle_data = value; return grpc_server_retry_throttle_data_ref(throttle_data); } +static void destroy_server_name(void* key, void* unused) { gpr_free(key); } + static const gpr_avl_vtable avl_vtable = { - gpr_free /* destroy_key */, copy_server_name, compare_server_name, + destroy_server_name, copy_server_name, compare_server_name, destroy_server_retry_throttle_data, copy_server_retry_throttle_data}; // @@ -164,19 +168,19 @@ void grpc_retry_throttle_map_init() { void grpc_retry_throttle_map_shutdown() { gpr_mu_destroy(&g_mu); - gpr_avl_unref(g_avl); + gpr_avl_unref(g_avl, NULL); } grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server( const char* server_name, int max_milli_tokens, int milli_token_ratio) { gpr_mu_lock(&g_mu); grpc_server_retry_throttle_data* throttle_data = - gpr_avl_get(g_avl, (char*)server_name); + gpr_avl_get(g_avl, (char*)server_name, NULL); if (throttle_data == NULL) { // Entry not found. Create a new one. throttle_data = grpc_server_retry_throttle_data_create( max_milli_tokens, milli_token_ratio, NULL); - g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data); + g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data, NULL); } else { if (throttle_data->max_milli_tokens != max_milli_tokens || throttle_data->milli_token_ratio != milli_token_ratio) { @@ -184,7 +188,7 @@ grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server( // the original one. throttle_data = grpc_server_retry_throttle_data_create( max_milli_tokens, milli_token_ratio, throttle_data); - g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data); + g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data, NULL); } else { // Entry found. Increase refcount. grpc_server_retry_throttle_data_ref(throttle_data); diff --git a/src/core/ext/filters/client_channel/subchannel_index.c b/src/core/ext/filters/client_channel/subchannel_index.c index a33ab950bf..15e42980af 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.c +++ b/src/core/ext/filters/client_channel/subchannel_index.c @@ -38,26 +38,8 @@ struct grpc_subchannel_key { grpc_subchannel_args args; }; -GPR_TLS_DECL(subchannel_index_exec_ctx); - static bool g_force_creation = false; -static void enter_ctx(grpc_exec_ctx *exec_ctx) { - GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == 0); - gpr_tls_set(&subchannel_index_exec_ctx, (intptr_t)exec_ctx); -} - -static void leave_ctx(grpc_exec_ctx *exec_ctx) { - GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == (intptr_t)exec_ctx); - gpr_tls_set(&subchannel_index_exec_ctx, 0); -} - -static grpc_exec_ctx *current_ctx() { - grpc_exec_ctx *c = (grpc_exec_ctx *)gpr_tls_get(&subchannel_index_exec_ctx); - GPR_ASSERT(c != NULL); - return c; -} - static grpc_subchannel_key *create_key( const grpc_subchannel_args *args, grpc_channel_args *(*copy_channel_args)(const grpc_channel_args *args)) { @@ -104,21 +86,25 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, gpr_free(k); } -static void sck_avl_destroy(void *p) { - grpc_subchannel_key_destroy(current_ctx(), p); +static void sck_avl_destroy(void *p, void *user_data) { + grpc_exec_ctx *exec_ctx = (grpc_exec_ctx *)user_data; + grpc_subchannel_key_destroy(exec_ctx, p); } -static void *sck_avl_copy(void *p) { return subchannel_key_copy(p); } +static void *sck_avl_copy(void *p, void *unused) { + return subchannel_key_copy(p); +} -static long sck_avl_compare(void *a, void *b) { +static long sck_avl_compare(void *a, void *b, void *unused) { return grpc_subchannel_key_compare(a, b); } -static void scv_avl_destroy(void *p) { - GRPC_SUBCHANNEL_WEAK_UNREF(current_ctx(), p, "subchannel_index"); +static void scv_avl_destroy(void *p, void *user_data) { + grpc_exec_ctx *exec_ctx = (grpc_exec_ctx *)user_data; + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, p, "subchannel_index"); } -static void *scv_avl_copy(void *p) { +static void *scv_avl_copy(void *p, void *unused) { GRPC_SUBCHANNEL_WEAK_REF(p, "subchannel_index"); return p; } @@ -133,38 +119,33 @@ static const gpr_avl_vtable subchannel_avl_vtable = { void grpc_subchannel_index_init(void) { g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable); gpr_mu_init(&g_mu); - gpr_tls_init(&subchannel_index_exec_ctx); } void grpc_subchannel_index_shutdown(void) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_mu_destroy(&g_mu); - gpr_avl_unref(g_subchannel_index); - gpr_tls_destroy(&subchannel_index_exec_ctx); + gpr_avl_unref(g_subchannel_index, &exec_ctx); + grpc_exec_ctx_finish(&exec_ctx); } grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx, grpc_subchannel_key *key) { - enter_ctx(exec_ctx); - // Lock, and take a reference to the subchannel index. // We don't need to do the search under a lock as avl's are immutable. gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx); gpr_mu_unlock(&g_mu); - grpc_subchannel *c = - GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(gpr_avl_get(index, key), "index_find"); - gpr_avl_unref(index); + grpc_subchannel *c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( + gpr_avl_get(index, key, exec_ctx), "index_find"); + gpr_avl_unref(index, exec_ctx); - leave_ctx(exec_ctx); return c; } grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, grpc_subchannel_key *key, grpc_subchannel *constructed) { - enter_ctx(exec_ctx); - grpc_subchannel *c = NULL; bool need_to_unref_constructed; @@ -174,11 +155,11 @@ grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, // Compare and swap loop: // - take a reference to the current index gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx); gpr_mu_unlock(&g_mu); // - Check to see if a subchannel already exists - c = gpr_avl_get(index, key); + c = gpr_avl_get(index, key, exec_ctx); if (c != NULL) { c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register"); } @@ -187,9 +168,9 @@ grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, need_to_unref_constructed = true; } else { // no -> update the avl and compare/swap - gpr_avl updated = - gpr_avl_add(gpr_avl_ref(index), subchannel_key_copy(key), - GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register")); + gpr_avl updated = gpr_avl_add( + gpr_avl_ref(index, exec_ctx), subchannel_key_copy(key), + GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), exec_ctx); // it may happen (but it's expected to be unlikely) // that some other thread has changed the index: @@ -201,12 +182,11 @@ grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, } gpr_mu_unlock(&g_mu); - gpr_avl_unref(updated); + gpr_avl_unref(updated, exec_ctx); } - gpr_avl_unref(index); + gpr_avl_unref(index, exec_ctx); } - leave_ctx(exec_ctx); if (need_to_unref_constructed) { GRPC_SUBCHANNEL_UNREF(exec_ctx, constructed, "index_register"); @@ -218,27 +198,26 @@ grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, grpc_subchannel_key *key, grpc_subchannel *constructed) { - enter_ctx(exec_ctx); - bool done = false; while (!done) { // Compare and swap loop: // - take a reference to the current index gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx); gpr_mu_unlock(&g_mu); // Check to see if this key still refers to the previously // registered subchannel - grpc_subchannel *c = gpr_avl_get(index, key); + grpc_subchannel *c = gpr_avl_get(index, key, exec_ctx); if (c != constructed) { - gpr_avl_unref(index); + gpr_avl_unref(index, exec_ctx); break; } // compare and swap the update (some other thread may have // mutated the index behind us) - gpr_avl updated = gpr_avl_remove(gpr_avl_ref(index), key); + gpr_avl updated = + gpr_avl_remove(gpr_avl_ref(index, exec_ctx), key, exec_ctx); gpr_mu_lock(&g_mu); if (index.root == g_subchannel_index.root) { @@ -247,11 +226,9 @@ void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, } gpr_mu_unlock(&g_mu); - gpr_avl_unref(updated); - gpr_avl_unref(index); + gpr_avl_unref(updated, exec_ctx); + gpr_avl_unref(index, exec_ctx); } - - leave_ctx(exec_ctx); } void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { diff --git a/src/core/lib/support/avl.c b/src/core/lib/support/avl.c index a6178fdbce..a58551e259 100644 --- a/src/core/lib/support/avl.c +++ b/src/core/lib/support/avl.c @@ -32,22 +32,23 @@ gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable) { return out; } -static gpr_avl_node *ref_node(gpr_avl_node *node) { +static gpr_avl_node *ref_node(gpr_avl_node *node, void *user_data) { if (node) { gpr_ref(&node->refs); } return node; } -static void unref_node(const gpr_avl_vtable *vtable, gpr_avl_node *node) { +static void unref_node(const gpr_avl_vtable *vtable, gpr_avl_node *node, + void *user_data) { if (node == NULL) { return; } if (gpr_unref(&node->refs)) { - vtable->destroy_key(node->key); - vtable->destroy_value(node->value); - unref_node(vtable, node->left); - unref_node(vtable, node->right); + vtable->destroy_key(node->key, user_data); + vtable->destroy_value(node->value, user_data); + unref_node(vtable, node->left, user_data); + unref_node(vtable, node->right, user_data); gpr_free(node); } } @@ -87,30 +88,30 @@ gpr_avl_node *new_node(void *key, void *value, gpr_avl_node *left, } static gpr_avl_node *get(const gpr_avl_vtable *vtable, gpr_avl_node *node, - void *key) { + void *key, void *user_data) { long cmp; if (node == NULL) { return NULL; } - cmp = vtable->compare_keys(node->key, key); + cmp = vtable->compare_keys(node->key, key, user_data); if (cmp == 0) { return node; } else if (cmp > 0) { - return get(vtable, node->left, key); + return get(vtable, node->left, key, user_data); } else { - return get(vtable, node->right, key); + return get(vtable, node->right, key, user_data); } } -void *gpr_avl_get(gpr_avl avl, void *key) { - gpr_avl_node *node = get(avl.vtable, avl.root, key); +void *gpr_avl_get(gpr_avl avl, void *key, void *user_data) { + gpr_avl_node *node = get(avl.vtable, avl.root, key, user_data); return node ? node->value : NULL; } -int gpr_avl_maybe_get(gpr_avl avl, void *key, void **value) { - gpr_avl_node *node = get(avl.vtable, avl.root, key); +int gpr_avl_maybe_get(gpr_avl avl, void *key, void **value, void *user_data) { + gpr_avl_node *node = get(avl.vtable, avl.root, key, user_data); if (node != NULL) { *value = node->value; return 1; @@ -120,70 +121,79 @@ int gpr_avl_maybe_get(gpr_avl avl, void *key, void **value) { static gpr_avl_node *rotate_left(const gpr_avl_vtable *vtable, void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { + gpr_avl_node *right, void *user_data) { gpr_avl_node *n = - new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), - new_node(key, value, left, ref_node(right->left)), - ref_node(right->right)); - unref_node(vtable, right); + new_node(vtable->copy_key(right->key, user_data), + vtable->copy_value(right->value, user_data), + new_node(key, value, left, ref_node(right->left, user_data)), + ref_node(right->right, user_data)); + unref_node(vtable, right, user_data); return n; } static gpr_avl_node *rotate_right(const gpr_avl_vtable *vtable, void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { - gpr_avl_node *n = new_node( - vtable->copy_key(left->key), vtable->copy_value(left->value), - ref_node(left->left), new_node(key, value, ref_node(left->right), right)); - unref_node(vtable, left); + gpr_avl_node *right, void *user_data) { + gpr_avl_node *n = + new_node(vtable->copy_key(left->key, user_data), + vtable->copy_value(left->value, user_data), + ref_node(left->left, user_data), + new_node(key, value, ref_node(left->right, user_data), right)); + unref_node(vtable, left, user_data); return n; } static gpr_avl_node *rotate_left_right(const gpr_avl_vtable *vtable, void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { + gpr_avl_node *right, void *user_data) { /* rotate_right(..., rotate_left(left), right) */ gpr_avl_node *n = new_node( - vtable->copy_key(left->right->key), - vtable->copy_value(left->right->value), - new_node(vtable->copy_key(left->key), vtable->copy_value(left->value), - ref_node(left->left), ref_node(left->right->left)), - new_node(key, value, ref_node(left->right->right), right)); - unref_node(vtable, left); + vtable->copy_key(left->right->key, user_data), + vtable->copy_value(left->right->value, user_data), + new_node(vtable->copy_key(left->key, user_data), + vtable->copy_value(left->value, user_data), + ref_node(left->left, user_data), + ref_node(left->right->left, user_data)), + new_node(key, value, ref_node(left->right->right, user_data), right)); + unref_node(vtable, left, user_data); return n; } static gpr_avl_node *rotate_right_left(const gpr_avl_vtable *vtable, void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { + gpr_avl_node *right, void *user_data) { /* rotate_left(..., left, rotate_right(right)) */ gpr_avl_node *n = new_node( - vtable->copy_key(right->left->key), - vtable->copy_value(right->left->value), - new_node(key, value, left, ref_node(right->left->left)), - new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), - ref_node(right->left->right), ref_node(right->right))); - unref_node(vtable, right); + vtable->copy_key(right->left->key, user_data), + vtable->copy_value(right->left->value, user_data), + new_node(key, value, left, ref_node(right->left->left, user_data)), + new_node(vtable->copy_key(right->key, user_data), + vtable->copy_value(right->value, user_data), + ref_node(right->left->right, user_data), + ref_node(right->right, user_data))); + unref_node(vtable, right, user_data); return n; } static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { + gpr_avl_node *right, void *user_data) { switch (node_height(left) - node_height(right)) { case 2: if (node_height(left->left) - node_height(left->right) == -1) { return assert_invariants( - rotate_left_right(vtable, key, value, left, right)); + rotate_left_right(vtable, key, value, left, right, user_data)); } else { - return assert_invariants(rotate_right(vtable, key, value, left, right)); + return assert_invariants( + rotate_right(vtable, key, value, left, right, user_data)); } case -2: if (node_height(right->left) - node_height(right->right) == 1) { return assert_invariants( - rotate_right_left(vtable, key, value, left, right)); + rotate_right_left(vtable, key, value, left, right, user_data)); } else { - return assert_invariants(rotate_left(vtable, key, value, left, right)); + return assert_invariants( + rotate_left(vtable, key, value, left, right, user_data)); } default: return assert_invariants(new_node(key, value, left, right)); @@ -191,30 +201,34 @@ static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key, } static gpr_avl_node *add_key(const gpr_avl_vtable *vtable, gpr_avl_node *node, - void *key, void *value) { + void *key, void *value, void *user_data) { long cmp; if (node == NULL) { return new_node(key, value, NULL, NULL); } - cmp = vtable->compare_keys(node->key, key); + cmp = vtable->compare_keys(node->key, key, user_data); if (cmp == 0) { - return new_node(key, value, ref_node(node->left), ref_node(node->right)); + return new_node(key, value, ref_node(node->left, user_data), + ref_node(node->right, user_data)); } else if (cmp > 0) { - return rebalance( - vtable, vtable->copy_key(node->key), vtable->copy_value(node->value), - add_key(vtable, node->left, key, value), ref_node(node->right)); + return rebalance(vtable, vtable->copy_key(node->key, user_data), + vtable->copy_value(node->value, user_data), + add_key(vtable, node->left, key, value, user_data), + ref_node(node->right, user_data), user_data); } else { - return rebalance(vtable, vtable->copy_key(node->key), - vtable->copy_value(node->value), ref_node(node->left), - add_key(vtable, node->right, key, value)); + return rebalance(vtable, vtable->copy_key(node->key, user_data), + vtable->copy_value(node->value, user_data), + ref_node(node->left, user_data), + add_key(vtable, node->right, key, value, user_data), + user_data); } } -gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) { +gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value, void *user_data) { gpr_avl_node *old_root = avl.root; - avl.root = add_key(avl.vtable, avl.root, key, value); + avl.root = add_key(avl.vtable, avl.root, key, value, user_data); assert_invariants(avl.root); - unref_node(avl.vtable, old_root); + unref_node(avl.vtable, old_root, user_data); return avl; } @@ -233,52 +247,61 @@ static gpr_avl_node *in_order_tail(gpr_avl_node *node) { } static gpr_avl_node *remove_key(const gpr_avl_vtable *vtable, - gpr_avl_node *node, void *key) { + gpr_avl_node *node, void *key, + void *user_data) { long cmp; if (node == NULL) { return NULL; } - cmp = vtable->compare_keys(node->key, key); + cmp = vtable->compare_keys(node->key, key, user_data); if (cmp == 0) { if (node->left == NULL) { - return ref_node(node->right); + return ref_node(node->right, user_data); } else if (node->right == NULL) { - return ref_node(node->left); + return ref_node(node->left, user_data); } else if (node->left->height < node->right->height) { gpr_avl_node *h = in_order_head(node->right); - return rebalance(vtable, vtable->copy_key(h->key), - vtable->copy_value(h->value), ref_node(node->left), - remove_key(vtable, node->right, h->key)); + return rebalance(vtable, vtable->copy_key(h->key, user_data), + vtable->copy_value(h->value, user_data), + ref_node(node->left, user_data), + remove_key(vtable, node->right, h->key, user_data), + user_data); } else { gpr_avl_node *h = in_order_tail(node->left); - return rebalance( - vtable, vtable->copy_key(h->key), vtable->copy_value(h->value), - remove_key(vtable, node->left, h->key), ref_node(node->right)); + return rebalance(vtable, vtable->copy_key(h->key, user_data), + vtable->copy_value(h->value, user_data), + remove_key(vtable, node->left, h->key, user_data), + ref_node(node->right, user_data), user_data); } } else if (cmp > 0) { - return rebalance( - vtable, vtable->copy_key(node->key), vtable->copy_value(node->value), - remove_key(vtable, node->left, key), ref_node(node->right)); + return rebalance(vtable, vtable->copy_key(node->key, user_data), + vtable->copy_value(node->value, user_data), + remove_key(vtable, node->left, key, user_data), + ref_node(node->right, user_data), user_data); } else { - return rebalance(vtable, vtable->copy_key(node->key), - vtable->copy_value(node->value), ref_node(node->left), - remove_key(vtable, node->right, key)); + return rebalance(vtable, vtable->copy_key(node->key, user_data), + vtable->copy_value(node->value, user_data), + ref_node(node->left, user_data), + remove_key(vtable, node->right, key, user_data), + user_data); } } -gpr_avl gpr_avl_remove(gpr_avl avl, void *key) { +gpr_avl gpr_avl_remove(gpr_avl avl, void *key, void *user_data) { gpr_avl_node *old_root = avl.root; - avl.root = remove_key(avl.vtable, avl.root, key); + avl.root = remove_key(avl.vtable, avl.root, key, user_data); assert_invariants(avl.root); - unref_node(avl.vtable, old_root); + unref_node(avl.vtable, old_root, user_data); return avl; } -gpr_avl gpr_avl_ref(gpr_avl avl) { - ref_node(avl.root); +gpr_avl gpr_avl_ref(gpr_avl avl, void *user_data) { + ref_node(avl.root, user_data); return avl; } -void gpr_avl_unref(gpr_avl avl) { unref_node(avl.vtable, avl.root); } +void gpr_avl_unref(gpr_avl avl, void *user_data) { + unref_node(avl.vtable, avl.root, user_data); +} int gpr_avl_is_empty(gpr_avl avl) { return avl.root == NULL; } |