• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2018 gRPC authors.
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 
19 #include <grpc/support/port_platform.h>
20 
21 #include "src/core/ext/filters/client_channel/local_subchannel_pool.h"
22 
23 #include "src/core/ext/filters/client_channel/subchannel.h"
24 
25 namespace grpc_core {
26 
LocalSubchannelPool()27 LocalSubchannelPool::LocalSubchannelPool() {
28   subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_);
29 }
30 
~LocalSubchannelPool()31 LocalSubchannelPool::~LocalSubchannelPool() {
32   grpc_avl_unref(subchannel_map_, nullptr);
33 }
34 
RegisterSubchannel(SubchannelKey * key,Subchannel * constructed)35 Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key,
36                                                     Subchannel* constructed) {
37   // Check to see if a subchannel already exists.
38   Subchannel* c =
39       static_cast<Subchannel*>(grpc_avl_get(subchannel_map_, key, nullptr));
40   if (c != nullptr) {
41     // The subchannel already exists. Reuse it.
42     c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse");
43     GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing");
44   } else {
45     // There hasn't been such subchannel. Add one.
46     subchannel_map_ = grpc_avl_add(subchannel_map_, new SubchannelKey(*key),
47                                    constructed, nullptr);
48     c = constructed;
49   }
50   return c;
51 }
52 
UnregisterSubchannel(SubchannelKey * key)53 void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) {
54   subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr);
55 }
56 
FindSubchannel(SubchannelKey * key)57 Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) {
58   Subchannel* c =
59       static_cast<Subchannel*>(grpc_avl_get(subchannel_map_, key, nullptr));
60   return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool");
61 }
62 
63 namespace {
64 
sck_avl_destroy(void * p,void *)65 void sck_avl_destroy(void* p, void* /*user_data*/) {
66   SubchannelKey* key = static_cast<SubchannelKey*>(p);
67   delete key;
68 }
69 
sck_avl_copy(void * p,void *)70 void* sck_avl_copy(void* p, void* /*unused*/) {
71   const SubchannelKey* key = static_cast<const SubchannelKey*>(p);
72   auto new_key = new SubchannelKey(*key);
73   return static_cast<void*>(new_key);
74 }
75 
sck_avl_compare(void * a,void * b,void *)76 long sck_avl_compare(void* a, void* b, void* /*unused*/) {
77   const SubchannelKey* key_a = static_cast<const SubchannelKey*>(a);
78   const SubchannelKey* key_b = static_cast<const SubchannelKey*>(b);
79   return key_a->Cmp(*key_b);
80 }
81 
scv_avl_destroy(void *,void *)82 void scv_avl_destroy(void* /*p*/, void* /*user_data*/) {}
83 
scv_avl_copy(void * p,void *)84 void* scv_avl_copy(void* p, void* /*unused*/) { return p; }
85 
86 }  // namespace
87 
88 const grpc_avl_vtable LocalSubchannelPool::subchannel_avl_vtable_ = {
89     sck_avl_destroy,  // destroy_key
90     sck_avl_copy,     // copy_key
91     sck_avl_compare,  // compare_keys
92     scv_avl_destroy,  // destroy_value
93     scv_avl_copy      // copy_value
94 };
95 
96 }  // namespace grpc_core
97