grpc 1.14.2 → 1.15.0.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.

Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +307 -12
  3. data/etc/roots.pem +40 -163
  4. data/include/grpc/grpc.h +49 -0
  5. data/include/grpc/grpc_security.h +0 -6
  6. data/include/grpc/grpc_security_constants.h +6 -0
  7. data/include/grpc/impl/codegen/grpc_types.h +17 -2
  8. data/include/grpc/impl/codegen/port_platform.h +41 -4
  9. data/include/grpc/support/sync.h +0 -16
  10. data/src/{cpp → core}/ext/filters/census/grpc_context.cc +0 -0
  11. data/src/core/ext/filters/client_channel/client_channel.cc +40 -11
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +11 -9
  13. data/src/core/ext/filters/client_channel/client_channel_channelz.h +4 -2
  14. data/src/core/ext/filters/client_channel/lb_policy.h +14 -11
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +67 -90
  16. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +108 -91
  17. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +79 -25
  18. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +40 -0
  19. data/src/core/ext/filters/client_channel/resolver.h +8 -0
  20. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +11 -3
  21. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +13 -10
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +18 -4
  23. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +13 -5
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +537 -0
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +6 -5
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +11 -0
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +29 -0
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +29 -0
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +9 -0
  30. data/src/core/ext/filters/client_channel/subchannel.cc +21 -8
  31. data/src/core/ext/filters/client_channel/subchannel.h +7 -0
  32. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  33. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +24 -0
  34. data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -7
  35. data/src/core/lib/channel/channel_stack.h +1 -1
  36. data/src/core/lib/channel/channel_trace.cc +1 -1
  37. data/src/core/lib/channel/channel_trace.h +1 -1
  38. data/src/core/lib/channel/channelz.cc +37 -27
  39. data/src/core/lib/channel/channelz.h +13 -4
  40. data/src/core/lib/channel/channelz_registry.cc +89 -4
  41. data/src/core/lib/channel/channelz_registry.h +56 -39
  42. data/src/core/lib/gpr/arena.cc +33 -40
  43. data/src/core/lib/gprpp/fork.cc +41 -33
  44. data/src/core/lib/gprpp/fork.h +13 -4
  45. data/src/core/lib/gprpp/mutex_lock.h +42 -0
  46. data/src/core/lib/gprpp/orphanable.h +4 -2
  47. data/src/core/lib/gprpp/ref_counted.h +4 -2
  48. data/src/core/lib/gprpp/ref_counted_ptr.h +65 -13
  49. data/src/core/lib/iomgr/call_combiner.h +4 -1
  50. data/src/core/lib/iomgr/ev_epoll1_linux.cc +77 -17
  51. data/src/core/lib/iomgr/ev_epollex_linux.cc +8 -26
  52. data/src/core/lib/iomgr/ev_epollsig_linux.cc +10 -28
  53. data/src/core/lib/iomgr/ev_poll_posix.cc +144 -35
  54. data/src/core/lib/iomgr/ev_posix.cc +58 -9
  55. data/src/core/lib/iomgr/ev_posix.h +22 -8
  56. data/src/core/lib/iomgr/exec_ctx.cc +6 -0
  57. data/src/core/lib/iomgr/exec_ctx.h +2 -0
  58. data/src/core/lib/iomgr/executor.cc +148 -72
  59. data/src/core/lib/iomgr/executor.h +39 -6
  60. data/src/core/lib/iomgr/fork_posix.cc +12 -1
  61. data/src/core/lib/iomgr/iocp_windows.cc +9 -4
  62. data/src/core/lib/iomgr/lockfree_event.cc +5 -1
  63. data/src/core/lib/iomgr/port.h +15 -2
  64. data/src/core/lib/iomgr/resolve_address_posix.cc +3 -2
  65. data/src/core/lib/iomgr/resolve_address_windows.cc +3 -2
  66. data/src/core/lib/iomgr/resource_quota.cc +78 -0
  67. data/src/core/lib/iomgr/resource_quota.h +16 -0
  68. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  69. data/src/core/lib/iomgr/socket_mutator.h +1 -1
  70. data/src/core/lib/iomgr/socket_windows.cc +33 -0
  71. data/src/core/lib/iomgr/socket_windows.h +6 -0
  72. data/src/core/lib/iomgr/tcp_windows.cc +2 -2
  73. data/src/core/lib/iomgr/tcp_windows.h +2 -0
  74. data/src/core/lib/iomgr/timer.h +3 -2
  75. data/src/core/lib/json/json.cc +2 -1
  76. data/src/core/lib/security/credentials/jwt/json_token.h +2 -0
  77. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -0
  78. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
  79. data/src/core/lib/security/security_connector/load_system_roots.h +29 -0
  80. data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +32 -0
  81. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +165 -0
  82. data/src/core/lib/security/security_connector/load_system_roots_linux.h +44 -0
  83. data/src/core/lib/security/security_connector/security_connector.cc +23 -4
  84. data/src/core/lib/security/transport/client_auth_filter.cc +0 -4
  85. data/src/core/lib/security/transport/server_auth_filter.cc +0 -2
  86. data/src/core/lib/surface/call.cc +7 -3
  87. data/src/core/lib/surface/channel.cc +18 -2
  88. data/src/core/lib/surface/completion_queue.cc +152 -15
  89. data/src/core/lib/surface/completion_queue.h +20 -1
  90. data/src/core/lib/surface/completion_queue_factory.cc +13 -4
  91. data/src/core/lib/surface/init.cc +2 -2
  92. data/src/core/lib/surface/init.h +0 -1
  93. data/src/core/lib/surface/version.cc +2 -2
  94. data/src/core/lib/transport/service_config.cc +2 -2
  95. data/src/core/lib/transport/service_config.h +3 -3
  96. data/src/core/lib/transport/transport.h +2 -0
  97. data/src/core/tsi/alts/crypt/aes_gcm.cc +2 -0
  98. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -0
  99. data/src/core/tsi/grpc_shadow_boringssl.h +3006 -0
  100. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -0
  101. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +5 -5
  102. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -0
  103. data/src/core/tsi/ssl_transport_security.cc +5 -3
  104. data/src/core/tsi/ssl_types.h +2 -0
  105. data/src/ruby/ext/grpc/extconf.rb +1 -26
  106. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -0
  107. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +18 -0
  108. data/src/ruby/lib/grpc/version.rb +1 -1
  109. data/src/ruby/spec/generic/client_stub_spec.rb +3 -3
  110. data/third_party/address_sorting/address_sorting.c +7 -2
  111. data/third_party/address_sorting/address_sorting_windows.c +43 -3
  112. data/third_party/address_sorting/include/address_sorting/address_sorting.h +3 -0
  113. metadata +40 -31
@@ -35,6 +35,10 @@
35
35
  #define GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC \
36
36
  "grpc.channelz_channel_node_creation_func"
37
37
 
38
+ // Channel arg key to signal that the channel is an internal channel.
39
+ #define GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL \
40
+ "grpc.channelz_channel_is_internal_channel"
41
+
38
42
  namespace grpc_core {
39
43
  namespace channelz {
40
44
 
@@ -45,7 +49,8 @@ class ChannelNodePeer;
45
49
  class ChannelNode : public RefCounted<ChannelNode> {
46
50
  public:
47
51
  static RefCountedPtr<ChannelNode> MakeChannelNode(
48
- grpc_channel* channel, size_t channel_tracer_max_nodes);
52
+ grpc_channel* channel, size_t channel_tracer_max_nodes,
53
+ bool is_top_level_channel);
49
54
 
50
55
  void RecordCallStarted();
51
56
  void RecordCallFailed() {
@@ -55,7 +60,8 @@ class ChannelNode : public RefCounted<ChannelNode> {
55
60
  gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1)));
56
61
  }
57
62
 
58
- char* RenderJSON();
63
+ grpc_json* RenderJson();
64
+ char* RenderJsonString();
59
65
 
60
66
  // helper for getting and populating connectivity state. It is virtual
61
67
  // because it allows the client_channel specific code to live in ext/
@@ -74,11 +80,13 @@ class ChannelNode : public RefCounted<ChannelNode> {
74
80
  bool ChannelIsDestroyed() { return channel_ == nullptr; }
75
81
 
76
82
  intptr_t channel_uuid() { return channel_uuid_; }
83
+ bool is_top_level_channel() { return is_top_level_channel_; }
77
84
 
78
85
  protected:
79
86
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
80
87
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
81
- ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
88
+ ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
89
+ bool is_top_level_channel);
82
90
  virtual ~ChannelNode();
83
91
 
84
92
  private:
@@ -92,6 +100,7 @@ class ChannelNode : public RefCounted<ChannelNode> {
92
100
  gpr_atm calls_failed_ = 0;
93
101
  gpr_atm last_call_started_millis_ = 0;
94
102
  intptr_t channel_uuid_;
103
+ bool is_top_level_channel_ = true;
95
104
  ManualConstructor<ChannelTrace> trace_;
96
105
  };
97
106
 
@@ -116,7 +125,7 @@ class SubchannelNode : public RefCounted<SubchannelNode> {
116
125
  // Creation functions
117
126
 
118
127
  typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,
119
- size_t);
128
+ size_t, bool);
120
129
 
121
130
  } // namespace channelz
122
131
  } // namespace grpc_core
@@ -19,16 +19,20 @@
19
19
  #include <grpc/impl/codegen/port_platform.h>
20
20
 
21
21
  #include "src/core/lib/channel/channel_trace.h"
22
+ #include "src/core/lib/channel/channelz.h"
22
23
  #include "src/core/lib/channel/channelz_registry.h"
23
24
  #include "src/core/lib/gpr/useful.h"
24
25
  #include "src/core/lib/gprpp/memory.h"
26
+ #include "src/core/lib/gprpp/mutex_lock.h"
25
27
 
26
28
  #include <grpc/support/alloc.h>
27
29
  #include <grpc/support/log.h>
30
+ #include <grpc/support/sync.h>
28
31
 
29
32
  #include <cstring>
30
33
 
31
34
  namespace grpc_core {
35
+ namespace channelz {
32
36
  namespace {
33
37
 
34
38
  // singleton instance of the registry.
@@ -49,12 +53,93 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
49
53
 
50
54
  ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
51
55
 
52
- void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
56
+ intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) {
57
+ MutexLock lock(&mu_);
58
+ entities_.push_back(entry);
59
+ intptr_t uuid = entities_.size();
60
+ return uuid;
61
+ }
62
+
63
+ void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) {
53
64
  GPR_ASSERT(uuid >= 1);
54
- gpr_mu_lock(&mu_);
65
+ MutexLock lock(&mu_);
55
66
  GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
56
- entities_[uuid - 1] = nullptr;
57
- gpr_mu_unlock(&mu_);
67
+ GPR_ASSERT(entities_[uuid - 1].type == type);
68
+ entities_[uuid - 1].object = nullptr;
69
+ entities_[uuid - 1].type = EntityType::kUnset;
70
+ }
71
+
72
+ void* ChannelzRegistry::InternalGetEntry(intptr_t uuid, EntityType type) {
73
+ MutexLock lock(&mu_);
74
+ if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
75
+ return nullptr;
76
+ }
77
+ if (entities_[uuid - 1].type == type) {
78
+ return entities_[uuid - 1].object;
79
+ } else {
80
+ return nullptr;
81
+ }
82
+ }
83
+
84
+ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
85
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
86
+ grpc_json* json = top_level_json;
87
+ grpc_json* json_iterator = nullptr;
88
+ InlinedVector<ChannelNode*, 10> top_level_channels;
89
+ // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
90
+ // reserved). However, we want to support requests coming in with
91
+ // start_channel_id=0, which signifies "give me everything." Hence this
92
+ // funky looking line below.
93
+ size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
94
+ for (size_t i = start_idx; i < entities_.size(); ++i) {
95
+ if (entities_[i].type == EntityType::kChannelNode) {
96
+ ChannelNode* channel_node =
97
+ static_cast<ChannelNode*>(entities_[i].object);
98
+ if (channel_node->is_top_level_channel()) {
99
+ top_level_channels.push_back(channel_node);
100
+ }
101
+ }
102
+ }
103
+ if (top_level_channels.size() > 0) {
104
+ // create list of channels
105
+ grpc_json* array_parent = grpc_json_create_child(
106
+ nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false);
107
+ for (size_t i = 0; i < top_level_channels.size(); ++i) {
108
+ grpc_json* channel_json = top_level_channels[i]->RenderJson();
109
+ json_iterator =
110
+ grpc_json_link_child(array_parent, channel_json, json_iterator);
111
+ }
112
+ }
113
+ // For now we do not have any pagination rules. In the future we could
114
+ // pick a constant for max_channels_sent for a GetTopChannels request.
115
+ // Tracking: https://github.com/grpc/grpc/issues/16019.
116
+ json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
117
+ GRPC_JSON_TRUE, false);
118
+ char* json_str = grpc_json_dump_to_string(top_level_json, 0);
119
+ grpc_json_destroy(top_level_json);
120
+ return json_str;
58
121
  }
59
122
 
123
+ } // namespace channelz
60
124
  } // namespace grpc_core
125
+
126
+ char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
127
+ return grpc_core::channelz::ChannelzRegistry::GetTopChannels(
128
+ start_channel_id);
129
+ }
130
+
131
+ char* grpc_channelz_get_channel(intptr_t channel_id) {
132
+ grpc_core::channelz::ChannelNode* channel_node =
133
+ grpc_core::channelz::ChannelzRegistry::GetChannelNode(channel_id);
134
+ if (channel_node == nullptr) {
135
+ return nullptr;
136
+ }
137
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
138
+ grpc_json* json = top_level_json;
139
+ grpc_json* channel_json = channel_node->RenderJson();
140
+ channel_json->key = "channel";
141
+ grpc_json_link_child(json, channel_json, nullptr);
142
+ char* json_str = grpc_json_dump_to_string(top_level_json, 0);
143
+ grpc_json_destroy(top_level_json);
144
+ return json_str;
145
+ }
@@ -22,11 +22,13 @@
22
22
  #include <grpc/impl/codegen/port_platform.h>
23
23
 
24
24
  #include "src/core/lib/channel/channel_trace.h"
25
+ #include "src/core/lib/channel/channelz.h"
25
26
  #include "src/core/lib/gprpp/inlined_vector.h"
26
27
 
27
28
  #include <stdint.h>
28
29
 
29
30
  namespace grpc_core {
31
+ namespace channelz {
30
32
 
31
33
  // singleton registry object to track all objects that are needed to support
32
34
  // channelz bookkeeping. All objects share globally distributed uuids.
@@ -35,26 +37,56 @@ class ChannelzRegistry {
35
37
  // To be called in grpc_init()
36
38
  static void Init();
37
39
 
38
- // To be callen in grpc_shutdown();
40
+ // To be called in grpc_shutdown();
39
41
  static void Shutdown();
40
42
 
41
- // globally registers a channelz Object. Returns its unique uuid
42
- template <typename Object>
43
- static intptr_t Register(Object* object) {
44
- return Default()->InternalRegister(object);
43
+ // Register/Unregister/Get for ChannelNode
44
+ static intptr_t RegisterChannelNode(ChannelNode* channel_node) {
45
+ RegistryEntry entry(channel_node, EntityType::kChannelNode);
46
+ return Default()->InternalRegisterEntry(entry);
47
+ }
48
+ static void UnregisterChannelNode(intptr_t uuid) {
49
+ Default()->InternalUnregisterEntry(uuid, EntityType::kChannelNode);
50
+ }
51
+ static ChannelNode* GetChannelNode(intptr_t uuid) {
52
+ void* gotten = Default()->InternalGetEntry(uuid, EntityType::kChannelNode);
53
+ return gotten == nullptr ? nullptr : static_cast<ChannelNode*>(gotten);
45
54
  }
46
55
 
47
- // globally unregisters the object that is associated to uuid.
48
- static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
56
+ // Register/Unregister/Get for SubchannelNode
57
+ static intptr_t RegisterSubchannelNode(SubchannelNode* channel_node) {
58
+ RegistryEntry entry(channel_node, EntityType::kSubchannelNode);
59
+ return Default()->InternalRegisterEntry(entry);
60
+ }
61
+ static void UnregisterSubchannelNode(intptr_t uuid) {
62
+ Default()->InternalUnregisterEntry(uuid, EntityType::kSubchannelNode);
63
+ }
64
+ static SubchannelNode* GetSubchannelNode(intptr_t uuid) {
65
+ void* gotten =
66
+ Default()->InternalGetEntry(uuid, EntityType::kSubchannelNode);
67
+ return gotten == nullptr ? nullptr : static_cast<SubchannelNode*>(gotten);
68
+ }
49
69
 
50
- // if object with uuid has previously been registered, returns the
51
- // Object associated with that uuid. Else returns nullptr.
52
- template <typename Object>
53
- static Object* Get(intptr_t uuid) {
54
- return Default()->InternalGet<Object>(uuid);
70
+ // Returns the allocated JSON string that represents the proto
71
+ // GetTopChannelsResponse as per channelz.proto.
72
+ static char* GetTopChannels(intptr_t start_channel_id) {
73
+ return Default()->InternalGetTopChannels(start_channel_id);
55
74
  }
56
75
 
57
76
  private:
77
+ enum class EntityType {
78
+ kChannelNode,
79
+ kSubchannelNode,
80
+ kUnset,
81
+ };
82
+
83
+ struct RegistryEntry {
84
+ RegistryEntry(void* object_in, EntityType type_in)
85
+ : object(object_in), type(type_in) {}
86
+ void* object;
87
+ EntityType type;
88
+ };
89
+
58
90
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
59
91
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
60
92
 
@@ -64,40 +96,25 @@ class ChannelzRegistry {
64
96
  // Returned the singleton instance of ChannelzRegistry;
65
97
  static ChannelzRegistry* Default();
66
98
 
67
- // globally registers a channelz Object. Returns its unique uuid
68
- template <typename Object>
69
- intptr_t InternalRegister(Object* object) {
70
- gpr_mu_lock(&mu_);
71
- entities_.push_back(static_cast<void*>(object));
72
- intptr_t uuid = entities_.size();
73
- gpr_mu_unlock(&mu_);
74
- return uuid;
75
- }
99
+ // globally registers an Entry. Returns its unique uuid
100
+ intptr_t InternalRegisterEntry(const RegistryEntry& entry);
76
101
 
77
- // globally unregisters the object that is associated to uuid.
78
- void InternalUnregister(intptr_t uuid);
79
-
80
- // if object with uuid has previously been registered, returns the
81
- // Object associated with that uuid. Else returns nullptr.
82
- template <typename Object>
83
- Object* InternalGet(intptr_t uuid) {
84
- gpr_mu_lock(&mu_);
85
- if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
86
- gpr_mu_unlock(&mu_);
87
- return nullptr;
88
- }
89
- Object* ret = static_cast<Object*>(entities_[uuid - 1]);
90
- gpr_mu_unlock(&mu_);
91
- return ret;
92
- }
102
+ // globally unregisters the object that is associated to uuid. Also does
103
+ // sanity check that an object doesn't try to unregister the wrong type.
104
+ void InternalUnregisterEntry(intptr_t uuid, EntityType type);
105
+
106
+ // if object with uuid has previously been registered as the correct type,
107
+ // returns the void* associated with that uuid. Else returns nullptr.
108
+ void* InternalGetEntry(intptr_t uuid, EntityType type);
93
109
 
94
- // private members
110
+ char* InternalGetTopChannels(intptr_t start_channel_id);
95
111
 
96
112
  // protects entities_ and uuid_
97
113
  gpr_mu mu_;
98
- InlinedVector<void*, 20> entities_;
114
+ InlinedVector<RegistryEntry, 20> entities_;
99
115
  };
100
116
 
117
+ } // namespace channelz
101
118
  } // namespace grpc_core
102
119
 
103
120
  #endif /* GRPC_CORE_LIB_CHANNEL_CHANNELZ_REGISTRY_H */
@@ -25,6 +25,7 @@
25
25
  #include <grpc/support/alloc.h>
26
26
  #include <grpc/support/atm.h>
27
27
  #include <grpc/support/log.h>
28
+ #include <grpc/support/sync.h>
28
29
 
29
30
  #include "src/core/lib/gpr/alloc.h"
30
31
 
@@ -36,8 +37,6 @@
36
37
 
37
38
  #ifdef SIMPLE_ARENA_FOR_DEBUGGING
38
39
 
39
- #include <grpc/support/sync.h>
40
-
41
40
  struct gpr_arena {
42
41
  gpr_mu mu;
43
42
  void** ptrs;
@@ -78,14 +77,17 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
78
77
  // would allow us to use the alignment actually needed by the caller.
79
78
 
80
79
  typedef struct zone {
81
- size_t size_begin;
82
- size_t size_end;
83
- gpr_atm next_atm;
80
+ zone* next;
84
81
  } zone;
85
82
 
86
83
  struct gpr_arena {
87
- gpr_atm size_so_far;
84
+ // Keep track of the total used size. We use this in our call sizing
85
+ // historesis.
86
+ gpr_atm total_used;
87
+ size_t initial_zone_size;
88
88
  zone initial_zone;
89
+ zone* last_zone;
90
+ gpr_mu arena_growth_mutex;
89
91
  };
90
92
 
91
93
  static void* zalloc_aligned(size_t size) {
@@ -98,16 +100,19 @@ gpr_arena* gpr_arena_create(size_t initial_size) {
98
100
  initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
99
101
  gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
100
102
  GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
101
- a->initial_zone.size_end = initial_size;
103
+ a->initial_zone_size = initial_size;
104
+ a->last_zone = &a->initial_zone;
105
+ gpr_mu_init(&a->arena_growth_mutex);
102
106
  return a;
103
107
  }
104
108
 
105
109
  size_t gpr_arena_destroy(gpr_arena* arena) {
106
- gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
107
- zone* z = (zone*)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
110
+ gpr_mu_destroy(&arena->arena_growth_mutex);
111
+ gpr_atm size = gpr_atm_no_barrier_load(&arena->total_used);
112
+ zone* z = arena->initial_zone.next;
108
113
  gpr_free_aligned(arena);
109
114
  while (z) {
110
- zone* next_z = (zone*)gpr_atm_no_barrier_load(&z->next_atm);
115
+ zone* next_z = z->next;
111
116
  gpr_free_aligned(z);
112
117
  z = next_z;
113
118
  }
@@ -116,37 +121,25 @@ size_t gpr_arena_destroy(gpr_arena* arena) {
116
121
 
117
122
  void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
118
123
  size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
119
- size_t start = static_cast<size_t>(
120
- gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
121
- zone* z = &arena->initial_zone;
122
- while (start > z->size_end) {
123
- zone* next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
124
- if (next_z == nullptr) {
125
- size_t next_z_size =
126
- static_cast<size_t>(gpr_atm_no_barrier_load(&arena->size_so_far));
127
- next_z = static_cast<zone*>(zalloc_aligned(
128
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
129
- next_z->size_begin = z->size_end;
130
- next_z->size_end = z->size_end + next_z_size;
131
- if (!gpr_atm_rel_cas(&z->next_atm, static_cast<gpr_atm>(NULL),
132
- (gpr_atm)next_z)) {
133
- gpr_free_aligned(next_z);
134
- next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
135
- }
136
- }
137
- z = next_z;
138
- }
139
- if (start + size > z->size_end) {
140
- return gpr_arena_alloc(arena, size);
124
+ size_t begin = gpr_atm_no_barrier_fetch_add(&arena->total_used, size);
125
+ if (begin + size <= arena->initial_zone_size) {
126
+ return reinterpret_cast<char*>(arena) +
127
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + begin;
128
+ } else {
129
+ // If the allocation isn't able to end in the initial zone, create a new
130
+ // zone for this allocation, and any unused space in the initial zone is
131
+ // wasted. This overflowing and wasting is uncommon because of our arena
132
+ // sizing historesis (that is, most calls should have a large enough initial
133
+ // zone and will not need to grow the arena).
134
+ gpr_mu_lock(&arena->arena_growth_mutex);
135
+ zone* z = static_cast<zone*>(
136
+ zalloc_aligned(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size));
137
+ arena->last_zone->next = z;
138
+ arena->last_zone = z;
139
+ gpr_mu_unlock(&arena->arena_growth_mutex);
140
+ return reinterpret_cast<char*>(z) +
141
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
141
142
  }
142
- GPR_ASSERT(start >= z->size_begin);
143
- GPR_ASSERT(start + size <= z->size_end);
144
- char* ptr = (z == &arena->initial_zone)
145
- ? reinterpret_cast<char*>(arena) +
146
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
147
- : reinterpret_cast<char*>(z) +
148
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
149
- return ptr + start - z->size_begin;
150
143
  }
151
144
 
152
145
  #endif // SIMPLE_ARENA_FOR_DEBUGGING
@@ -157,11 +157,11 @@ class ThreadState {
157
157
  } // namespace
158
158
 
159
159
  void Fork::GlobalInit() {
160
- if (!overrideEnabled_) {
160
+ if (!override_enabled_) {
161
161
  #ifdef GRPC_ENABLE_FORK_SUPPORT
162
- supportEnabled_ = true;
162
+ support_enabled_ = true;
163
163
  #else
164
- supportEnabled_ = false;
164
+ support_enabled_ = false;
165
165
  #endif
166
166
  bool env_var_set = false;
167
167
  char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
@@ -172,7 +172,7 @@ void Fork::GlobalInit() {
172
172
  "False", "FALSE", "0"};
173
173
  for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
174
174
  if (0 == strcmp(env, truthy[i])) {
175
- supportEnabled_ = true;
175
+ support_enabled_ = true;
176
176
  env_var_set = true;
177
177
  break;
178
178
  }
@@ -180,7 +180,7 @@ void Fork::GlobalInit() {
180
180
  if (!env_var_set) {
181
181
  for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
182
182
  if (0 == strcmp(env, falsey[i])) {
183
- supportEnabled_ = false;
183
+ support_enabled_ = false;
184
184
  env_var_set = true;
185
185
  break;
186
186
  }
@@ -189,72 +189,80 @@ void Fork::GlobalInit() {
189
189
  gpr_free(env);
190
190
  }
191
191
  }
192
- if (supportEnabled_) {
193
- execCtxState_ = grpc_core::New<internal::ExecCtxState>();
194
- threadState_ = grpc_core::New<internal::ThreadState>();
192
+ if (support_enabled_) {
193
+ exec_ctx_state_ = grpc_core::New<internal::ExecCtxState>();
194
+ thread_state_ = grpc_core::New<internal::ThreadState>();
195
195
  }
196
196
  }
197
197
 
198
198
  void Fork::GlobalShutdown() {
199
- if (supportEnabled_) {
200
- grpc_core::Delete(execCtxState_);
201
- grpc_core::Delete(threadState_);
199
+ if (support_enabled_) {
200
+ grpc_core::Delete(exec_ctx_state_);
201
+ grpc_core::Delete(thread_state_);
202
202
  }
203
203
  }
204
204
 
205
- bool Fork::Enabled() { return supportEnabled_; }
205
+ bool Fork::Enabled() { return support_enabled_; }
206
206
 
207
207
  // Testing Only
208
208
  void Fork::Enable(bool enable) {
209
- overrideEnabled_ = true;
210
- supportEnabled_ = enable;
209
+ override_enabled_ = true;
210
+ support_enabled_ = enable;
211
211
  }
212
212
 
213
213
  void Fork::IncExecCtxCount() {
214
- if (supportEnabled_) {
215
- execCtxState_->IncExecCtxCount();
214
+ if (support_enabled_) {
215
+ exec_ctx_state_->IncExecCtxCount();
216
216
  }
217
217
  }
218
218
 
219
219
  void Fork::DecExecCtxCount() {
220
- if (supportEnabled_) {
221
- execCtxState_->DecExecCtxCount();
220
+ if (support_enabled_) {
221
+ exec_ctx_state_->DecExecCtxCount();
222
222
  }
223
223
  }
224
224
 
225
+ void Fork::SetResetChildPollingEngineFunc(
226
+ Fork::child_postfork_func reset_child_polling_engine) {
227
+ reset_child_polling_engine_ = reset_child_polling_engine;
228
+ }
229
+ Fork::child_postfork_func Fork::GetResetChildPollingEngineFunc() {
230
+ return reset_child_polling_engine_;
231
+ }
232
+
225
233
  bool Fork::BlockExecCtx() {
226
- if (supportEnabled_) {
227
- return execCtxState_->BlockExecCtx();
234
+ if (support_enabled_) {
235
+ return exec_ctx_state_->BlockExecCtx();
228
236
  }
229
237
  return false;
230
238
  }
231
239
 
232
240
  void Fork::AllowExecCtx() {
233
- if (supportEnabled_) {
234
- execCtxState_->AllowExecCtx();
241
+ if (support_enabled_) {
242
+ exec_ctx_state_->AllowExecCtx();
235
243
  }
236
244
  }
237
245
 
238
246
  void Fork::IncThreadCount() {
239
- if (supportEnabled_) {
240
- threadState_->IncThreadCount();
247
+ if (support_enabled_) {
248
+ thread_state_->IncThreadCount();
241
249
  }
242
250
  }
243
251
 
244
252
  void Fork::DecThreadCount() {
245
- if (supportEnabled_) {
246
- threadState_->DecThreadCount();
253
+ if (support_enabled_) {
254
+ thread_state_->DecThreadCount();
247
255
  }
248
256
  }
249
257
  void Fork::AwaitThreads() {
250
- if (supportEnabled_) {
251
- threadState_->AwaitThreads();
258
+ if (support_enabled_) {
259
+ thread_state_->AwaitThreads();
252
260
  }
253
261
  }
254
262
 
255
- internal::ExecCtxState* Fork::execCtxState_ = nullptr;
256
- internal::ThreadState* Fork::threadState_ = nullptr;
257
- bool Fork::supportEnabled_ = false;
258
- bool Fork::overrideEnabled_ = false;
259
-
263
+ internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr;
264
+ internal::ThreadState* Fork::thread_state_ = nullptr;
265
+ bool Fork::support_enabled_ = false;
266
+ bool Fork::override_enabled_ = false;
267
+ Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr;
260
268
  } // namespace grpc_core