grpc 1.1.2 → 1.2.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.
- checksums.yaml +4 -4
- data/Makefile +1257 -404
- data/etc/roots.pem +189 -102
- data/include/grpc/census.h +7 -7
- data/include/grpc/compression.h +4 -4
- data/include/grpc/grpc.h +13 -7
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
- data/include/grpc/impl/codegen/grpc_types.h +39 -30
- data/include/grpc/impl/codegen/slice.h +24 -6
- data/include/grpc/impl/codegen/sync.h +8 -0
- data/include/grpc/load_reporting.h +63 -0
- data/include/grpc/slice.h +37 -1
- data/include/grpc/slice_buffer.h +7 -0
- data/include/grpc/support/alloc.h +3 -0
- data/include/grpc/support/useful.h +3 -0
- data/src/core/ext/census/gen/census.pb.h +1 -1
- data/src/core/ext/census/gen/trace_context.pb.c +9 -36
- data/src/core/ext/census/gen/trace_context.pb.h +20 -26
- data/src/core/ext/census/grpc_filter.c +3 -5
- data/src/core/ext/census/trace_context.c +1 -1
- data/src/core/ext/census/trace_context.h +3 -0
- data/src/core/ext/census/trace_label.h +61 -0
- data/src/core/ext/census/trace_propagation.h +63 -0
- data/src/core/ext/census/trace_status.h +45 -0
- data/src/core/ext/census/trace_string.h +50 -0
- data/src/core/ext/census/tracing.c +31 -11
- data/src/core/ext/census/tracing.h +124 -0
- data/src/core/ext/client_channel/client_channel.c +456 -368
- data/src/core/ext/client_channel/client_channel.h +4 -0
- data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
- data/src/core/ext/client_channel/connector.c +3 -3
- data/src/core/ext/client_channel/connector.h +4 -3
- data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
- data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
- data/src/core/ext/client_channel/http_proxy.c +125 -0
- data/src/core/ext/client_channel/http_proxy.h +39 -0
- data/src/core/ext/client_channel/lb_policy.c +56 -35
- data/src/core/ext/client_channel/lb_policy.h +46 -39
- data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
- data/src/core/ext/client_channel/parse_address.c +32 -6
- data/src/core/ext/client_channel/proxy_mapper.c +63 -0
- data/src/core/ext/client_channel/proxy_mapper.h +89 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
- data/src/core/ext/client_channel/resolver.c +16 -9
- data/src/core/ext/client_channel/resolver.h +23 -12
- data/src/core/ext/client_channel/resolver_factory.h +1 -0
- data/src/core/ext/client_channel/resolver_registry.c +15 -11
- data/src/core/ext/client_channel/resolver_registry.h +5 -3
- data/src/core/ext/client_channel/subchannel.c +44 -27
- data/src/core/ext/client_channel/subchannel.h +6 -2
- data/src/core/ext/client_channel/uri_parser.c +26 -14
- data/src/core/ext/client_channel/uri_parser.h +3 -1
- data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
- data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
- data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
- data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
- data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
- data/src/core/ext/load_reporting/load_reporting.c +20 -0
- data/src/core/ext/load_reporting/load_reporting.h +1 -16
- data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
- data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
- data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
- data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
- data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
- data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
- data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
- data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
- data/src/core/lib/channel/channel_stack.c +14 -44
- data/src/core/lib/channel/channel_stack.h +10 -17
- data/src/core/lib/channel/channel_stack_builder.c +2 -3
- data/src/core/lib/channel/compress_filter.c +54 -46
- data/src/core/lib/channel/connected_channel.c +4 -4
- data/src/core/lib/channel/connected_channel.h +5 -0
- data/src/core/lib/channel/context.h +3 -0
- data/src/core/lib/channel/deadline_filter.c +61 -61
- data/src/core/lib/channel/deadline_filter.h +8 -5
- data/src/core/lib/channel/handshaker.c +47 -7
- data/src/core/lib/channel/handshaker.h +21 -3
- data/src/core/lib/channel/http_client_filter.c +149 -99
- data/src/core/lib/channel/http_server_filter.c +163 -147
- data/src/core/lib/channel/message_size_filter.c +15 -10
- data/src/core/lib/compression/algorithm_metadata.h +4 -4
- data/src/core/lib/compression/compression.c +17 -23
- data/src/core/lib/http/httpcli.c +3 -2
- data/src/core/lib/http/httpcli.h +2 -1
- data/src/core/lib/http/httpcli_security_connector.c +2 -3
- data/src/core/lib/http/parser.c +2 -2
- data/src/core/lib/iomgr/closure.c +6 -3
- data/src/core/lib/iomgr/closure.h +4 -2
- data/src/core/lib/iomgr/combiner.c +35 -5
- data/src/core/lib/iomgr/combiner.h +21 -2
- data/src/core/lib/iomgr/endpoint.c +3 -2
- data/src/core/lib/iomgr/endpoint.h +3 -2
- data/src/core/lib/iomgr/error.c +60 -94
- data/src/core/lib/iomgr/error.h +7 -10
- data/src/core/lib/iomgr/error_internal.h +54 -0
- data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
- data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
- data/src/core/lib/iomgr/ev_posix.c +7 -8
- data/src/core/lib/iomgr/ev_posix.h +4 -4
- data/src/core/lib/iomgr/exec_ctx.c +11 -6
- data/src/core/lib/iomgr/exec_ctx.h +11 -14
- data/src/core/lib/iomgr/executor.c +2 -2
- data/src/core/lib/iomgr/load_file.c +1 -1
- data/src/core/lib/iomgr/network_status_tracker.c +5 -81
- data/src/core/lib/iomgr/pollset.h +1 -3
- data/src/core/lib/iomgr/pollset_set.h +2 -1
- data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
- data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
- data/src/core/lib/iomgr/pollset_uv.c +25 -11
- data/src/core/lib/iomgr/pollset_windows.c +0 -11
- data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
- data/src/core/lib/iomgr/resource_quota.c +41 -11
- data/src/core/lib/iomgr/resource_quota.h +6 -0
- data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
- data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
- data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
- data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
- data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
- data/src/core/lib/iomgr/tcp_posix.c +4 -5
- data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
- data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
- data/src/core/lib/iomgr/tcp_uv.c +11 -5
- data/src/core/lib/iomgr/tcp_windows.c +20 -7
- data/src/core/lib/iomgr/timer_generic.c +15 -22
- data/src/core/lib/iomgr/timer_generic.h +1 -1
- data/src/core/lib/iomgr/timer_uv.c +10 -6
- data/src/core/lib/iomgr/timer_uv.h +1 -1
- data/src/core/lib/iomgr/udp_server.c +45 -6
- data/src/core/lib/iomgr/udp_server.h +7 -1
- data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
- data/src/core/lib/json/json.c +1 -2
- data/src/core/lib/profiling/basic_timers.c +17 -3
- data/src/core/lib/security/context/security_context.c +3 -10
- data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
- data/src/core/lib/security/credentials/credentials.c +48 -2
- data/src/core/lib/security/credentials/credentials.h +13 -0
- data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
- data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
- data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
- data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
- data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
- data/src/core/lib/security/transport/client_auth_filter.c +72 -47
- data/src/core/lib/security/transport/lb_targets_info.c +70 -0
- data/src/core/lib/security/transport/lb_targets_info.h +47 -0
- data/src/core/lib/security/transport/secure_endpoint.c +3 -3
- data/src/core/lib/security/transport/security_connector.c +125 -28
- data/src/core/lib/security/transport/security_connector.h +4 -3
- data/src/core/lib/security/transport/security_handshaker.c +13 -9
- data/src/core/lib/security/transport/server_auth_filter.c +31 -40
- data/src/core/lib/security/util/b64.c +1 -1
- data/src/core/lib/slice/slice.c +110 -20
- data/src/core/lib/slice/slice_buffer.c +92 -39
- data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
- data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
- data/src/core/lib/slice/slice_intern.c +346 -0
- data/src/core/lib/slice/slice_internal.h +15 -0
- data/src/core/lib/slice/slice_string_helpers.c +5 -0
- data/src/core/lib/slice/slice_string_helpers.h +5 -0
- data/src/core/lib/support/alloc.c +26 -1
- data/src/core/lib/support/cmdline.c +2 -4
- data/src/core/lib/support/cpu_posix.c +2 -7
- data/src/core/lib/support/histogram.c +1 -2
- data/src/core/lib/support/log_posix.c +8 -4
- data/src/core/lib/support/spinlock.h +52 -0
- data/src/core/lib/support/subprocess_posix.c +1 -2
- data/src/core/lib/support/sync.c +7 -1
- data/src/core/lib/support/sync_posix.c +9 -0
- data/src/core/lib/support/time_windows.c +7 -1
- data/src/core/lib/surface/call.c +647 -629
- data/src/core/lib/surface/call.h +4 -1
- data/src/core/lib/surface/call_details.c +8 -2
- data/src/core/lib/surface/call_log_batch.c +17 -6
- data/src/core/lib/surface/channel.c +49 -59
- data/src/core/lib/surface/channel.h +5 -6
- data/src/core/lib/surface/completion_queue.c +16 -45
- data/src/core/lib/surface/completion_queue.h +0 -3
- data/src/core/lib/surface/init.c +6 -2
- data/src/core/lib/surface/init_secure.c +1 -1
- data/src/core/lib/surface/lame_client.c +14 -4
- data/src/core/lib/surface/server.c +79 -82
- data/src/core/lib/surface/validate_metadata.c +46 -15
- data/src/core/lib/surface/validate_metadata.h +43 -0
- data/src/core/lib/surface/version.c +2 -2
- data/src/core/lib/transport/bdp_estimator.c +104 -0
- data/src/core/lib/transport/bdp_estimator.h +76 -0
- data/src/core/lib/transport/connectivity_state.c +33 -13
- data/src/core/lib/transport/connectivity_state.h +15 -5
- data/src/core/lib/transport/error_utils.c +124 -0
- data/src/core/lib/transport/error_utils.h +56 -0
- data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
- data/src/core/lib/transport/metadata.c +259 -503
- data/src/core/lib/transport/metadata.h +69 -68
- data/src/core/lib/transport/metadata_batch.c +183 -63
- data/src/core/lib/transport/metadata_batch.h +50 -26
- data/src/core/lib/transport/pid_controller.c +28 -8
- data/src/core/lib/transport/pid_controller.h +15 -2
- data/src/core/lib/transport/service_config.c +21 -18
- data/src/core/lib/transport/service_config.h +5 -5
- data/src/core/lib/transport/static_metadata.c +753 -112
- data/src/core/lib/transport/static_metadata.h +403 -264
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
- data/src/core/lib/transport/timeout_encoding.c +11 -9
- data/src/core/lib/transport/timeout_encoding.h +3 -1
- data/src/core/lib/transport/transport.c +47 -87
- data/src/core/lib/transport/transport.h +20 -25
- data/src/core/lib/transport/transport_op_string.c +7 -19
- data/src/core/lib/tsi/fake_transport_security.c +2 -4
- data/src/core/lib/tsi/ssl_transport_security.c +7 -16
- data/src/core/lib/tsi/transport_security.c +2 -4
- data/src/ruby/ext/grpc/extconf.rb +4 -1
- data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
- data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
- data/src/ruby/ext/grpc/rb_call.c +47 -46
- data/src/ruby/ext/grpc/rb_channel.c +21 -6
- data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
- data/src/ruby/ext/grpc/rb_server.c +6 -4
- data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +33 -9
@@ -0,0 +1,56 @@
|
|
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
|
+
#ifndef GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
|
35
|
+
#define GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
|
36
|
+
|
37
|
+
#include "src/core/lib/iomgr/error.h"
|
38
|
+
#include "src/core/lib/transport/http2_errors.h"
|
39
|
+
|
40
|
+
/// A utility function to get the status code and message to be returned
|
41
|
+
/// to the application. If not set in the top-level message, looks
|
42
|
+
/// through child errors until it finds the first one with these attributes.
|
43
|
+
/// All attributes are pulled from the same child error. If any of the
|
44
|
+
/// attributes (code, msg, http_status) are unneeded, they can be passed as
|
45
|
+
/// NULL.
|
46
|
+
void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
|
47
|
+
grpc_status_code *code, const char **msg,
|
48
|
+
grpc_http2_error_code *http_status);
|
49
|
+
|
50
|
+
/// A utility function to check whether there is a clear status code that
|
51
|
+
/// doesn't need to be guessed in \a error. This means that \a error or some
|
52
|
+
/// child has GRPC_ERROR_INT_GRPC_STATUS set, or that it is GRPC_ERROR_NONE or
|
53
|
+
/// GRPC_ERROR_CANCELLED
|
54
|
+
bool grpc_error_has_clear_grpc_status(grpc_error *error);
|
55
|
+
|
56
|
+
#endif /* GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H */
|
@@ -31,26 +31,26 @@
|
|
31
31
|
*
|
32
32
|
*/
|
33
33
|
|
34
|
-
#ifndef
|
35
|
-
#define
|
34
|
+
#ifndef GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H
|
35
|
+
#define GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H
|
36
36
|
|
37
37
|
/* error codes for RST_STREAM from http2 draft 14 section 7 */
|
38
38
|
typedef enum {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
39
|
+
GRPC_HTTP2_NO_ERROR = 0x0,
|
40
|
+
GRPC_HTTP2_PROTOCOL_ERROR = 0x1,
|
41
|
+
GRPC_HTTP2_INTERNAL_ERROR = 0x2,
|
42
|
+
GRPC_HTTP2_FLOW_CONTROL_ERROR = 0x3,
|
43
|
+
GRPC_HTTP2_SETTINGS_TIMEOUT = 0x4,
|
44
|
+
GRPC_HTTP2_STREAM_CLOSED = 0x5,
|
45
|
+
GRPC_HTTP2_FRAME_SIZE_ERROR = 0x6,
|
46
|
+
GRPC_HTTP2_REFUSED_STREAM = 0x7,
|
47
|
+
GRPC_HTTP2_CANCEL = 0x8,
|
48
|
+
GRPC_HTTP2_COMPRESSION_ERROR = 0x9,
|
49
|
+
GRPC_HTTP2_CONNECT_ERROR = 0xa,
|
50
|
+
GRPC_HTTP2_ENHANCE_YOUR_CALM = 0xb,
|
51
|
+
GRPC_HTTP2_INADEQUATE_SECURITY = 0xc,
|
52
52
|
/* force use of a default clause */
|
53
|
-
|
54
|
-
}
|
53
|
+
GRPC_HTTP2__ERROR_DO_NOT_USE = -1
|
54
|
+
} grpc_http2_error_code;
|
55
55
|
|
56
|
-
#endif /*
|
56
|
+
#endif /* GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H */
|
@@ -48,12 +48,11 @@
|
|
48
48
|
#include "src/core/lib/iomgr/iomgr_internal.h"
|
49
49
|
#include "src/core/lib/profiling/timers.h"
|
50
50
|
#include "src/core/lib/slice/slice_internal.h"
|
51
|
+
#include "src/core/lib/slice/slice_string_helpers.h"
|
51
52
|
#include "src/core/lib/support/murmur_hash.h"
|
52
53
|
#include "src/core/lib/support/string.h"
|
53
54
|
#include "src/core/lib/transport/static_metadata.h"
|
54
55
|
|
55
|
-
grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
|
56
|
-
|
57
56
|
/* There are two kinds of mdelem and mdstr instances.
|
58
57
|
* Static instances are declared in static_metadata.{h,c} and
|
59
58
|
* are initialized by grpc_mdctx_global_init().
|
@@ -63,9 +62,6 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
|
|
63
62
|
* used to determine which kind of element a pointer refers to.
|
64
63
|
*/
|
65
64
|
|
66
|
-
#define INITIAL_STRTAB_CAPACITY 4
|
67
|
-
#define INITIAL_MDTAB_CAPACITY 4
|
68
|
-
|
69
65
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
70
66
|
#define DEBUG_ARGS , const char *file, int line
|
71
67
|
#define FWD_DEBUG_ARGS , file, line
|
@@ -76,37 +72,20 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
|
|
76
72
|
#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s))
|
77
73
|
#endif
|
78
74
|
|
79
|
-
#define
|
80
|
-
|
81
|
-
#define
|
82
|
-
|
83
|
-
typedef void (*destroy_user_data_func)(void *user_data);
|
84
|
-
|
85
|
-
#define SIZE_IN_DECODER_TABLE_NOT_SET -1
|
86
|
-
/* Shadow structure for grpc_mdstr for non-static values */
|
87
|
-
typedef struct internal_string {
|
88
|
-
/* must be byte compatible with grpc_mdstr */
|
89
|
-
grpc_slice slice;
|
90
|
-
uint32_t hash;
|
91
|
-
|
92
|
-
/* private only data */
|
93
|
-
gpr_atm refcnt;
|
94
|
-
|
95
|
-
uint8_t has_base64_and_huffman_encoded;
|
96
|
-
grpc_slice_refcount refcount;
|
75
|
+
#define INITIAL_SHARD_CAPACITY 8
|
76
|
+
#define LOG2_SHARD_COUNT 4
|
77
|
+
#define SHARD_COUNT ((size_t)(1 << LOG2_SHARD_COUNT))
|
97
78
|
|
98
|
-
|
79
|
+
#define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity))
|
80
|
+
#define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1))
|
99
81
|
|
100
|
-
|
101
|
-
|
102
|
-
struct internal_string *bucket_next;
|
103
|
-
} internal_string;
|
82
|
+
typedef void (*destroy_user_data_func)(void *user_data);
|
104
83
|
|
105
|
-
/* Shadow structure for
|
106
|
-
typedef struct
|
107
|
-
/* must be byte compatible with
|
108
|
-
|
109
|
-
|
84
|
+
/* Shadow structure for grpc_mdelem_data for interned elements */
|
85
|
+
typedef struct interned_metadata {
|
86
|
+
/* must be byte compatible with grpc_mdelem_data */
|
87
|
+
grpc_slice key;
|
88
|
+
grpc_slice value;
|
110
89
|
|
111
90
|
/* private only data */
|
112
91
|
gpr_atm refcnt;
|
@@ -115,19 +94,22 @@ typedef struct internal_metadata {
|
|
115
94
|
gpr_atm destroy_user_data;
|
116
95
|
gpr_atm user_data;
|
117
96
|
|
118
|
-
struct
|
119
|
-
}
|
97
|
+
struct interned_metadata *bucket_next;
|
98
|
+
} interned_metadata;
|
120
99
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
100
|
+
/* Shadow structure for grpc_mdelem_data for allocated elements */
|
101
|
+
typedef struct allocated_metadata {
|
102
|
+
/* must be byte compatible with grpc_mdelem_data */
|
103
|
+
grpc_slice key;
|
104
|
+
grpc_slice value;
|
105
|
+
|
106
|
+
/* private only data */
|
107
|
+
gpr_atm refcnt;
|
108
|
+
} allocated_metadata;
|
127
109
|
|
128
110
|
typedef struct mdtab_shard {
|
129
111
|
gpr_mu mu;
|
130
|
-
|
112
|
+
interned_metadata **elems;
|
131
113
|
size_t count;
|
132
114
|
size_t capacity;
|
133
115
|
/** Estimate of the number of unreferenced mdelems in the hash table.
|
@@ -136,102 +118,25 @@ typedef struct mdtab_shard {
|
|
136
118
|
gpr_atm free_estimate;
|
137
119
|
} mdtab_shard;
|
138
120
|
|
139
|
-
|
140
|
-
#define LOG2_MDTAB_SHARD_COUNT 4
|
141
|
-
#define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT))
|
142
|
-
#define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT))
|
143
|
-
|
144
|
-
/* hash seed: decided at initialization time */
|
145
|
-
static uint32_t g_hash_seed;
|
146
|
-
static int g_forced_hash_seed = 0;
|
147
|
-
|
148
|
-
/* linearly probed hash tables for static element lookup */
|
149
|
-
static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2];
|
150
|
-
static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2];
|
151
|
-
static size_t g_static_strtab_maxprobe;
|
152
|
-
static size_t g_static_mdtab_maxprobe;
|
153
|
-
|
154
|
-
static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT];
|
155
|
-
static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT];
|
121
|
+
static mdtab_shard g_shards[SHARD_COUNT];
|
156
122
|
|
157
123
|
static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard);
|
158
124
|
|
159
|
-
void grpc_test_only_set_metadata_hash_seed(uint32_t seed) {
|
160
|
-
g_hash_seed = seed;
|
161
|
-
g_forced_hash_seed = 1;
|
162
|
-
}
|
163
|
-
|
164
125
|
void grpc_mdctx_global_init(void) {
|
165
|
-
size_t i, j;
|
166
|
-
if (!g_forced_hash_seed) {
|
167
|
-
g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
|
168
|
-
}
|
169
|
-
g_static_strtab_maxprobe = 0;
|
170
|
-
g_static_mdtab_maxprobe = 0;
|
171
|
-
/* build static tables */
|
172
|
-
memset(g_static_mdtab, 0, sizeof(g_static_mdtab));
|
173
|
-
memset(g_static_strtab, 0, sizeof(g_static_strtab));
|
174
|
-
for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
|
175
|
-
grpc_mdstr *elem = &grpc_static_mdstr_table[i];
|
176
|
-
const char *str = grpc_static_metadata_strings[i];
|
177
|
-
uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed);
|
178
|
-
*(grpc_slice *)&elem->slice = grpc_slice_from_static_string(str);
|
179
|
-
*(uint32_t *)&elem->hash = hash;
|
180
|
-
for (j = 0;; j++) {
|
181
|
-
size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab);
|
182
|
-
if (g_static_strtab[idx] == NULL) {
|
183
|
-
g_static_strtab[idx] = &grpc_static_mdstr_table[i];
|
184
|
-
break;
|
185
|
-
}
|
186
|
-
}
|
187
|
-
if (j > g_static_strtab_maxprobe) {
|
188
|
-
g_static_strtab_maxprobe = j;
|
189
|
-
}
|
190
|
-
}
|
191
|
-
for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
|
192
|
-
grpc_mdelem *elem = &grpc_static_mdelem_table[i];
|
193
|
-
grpc_mdstr *key =
|
194
|
-
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]];
|
195
|
-
grpc_mdstr *value =
|
196
|
-
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]];
|
197
|
-
uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash);
|
198
|
-
*(grpc_mdstr **)&elem->key = key;
|
199
|
-
*(grpc_mdstr **)&elem->value = value;
|
200
|
-
for (j = 0;; j++) {
|
201
|
-
size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab);
|
202
|
-
if (g_static_mdtab[idx] == NULL) {
|
203
|
-
g_static_mdtab[idx] = elem;
|
204
|
-
break;
|
205
|
-
}
|
206
|
-
}
|
207
|
-
if (j > g_static_mdtab_maxprobe) {
|
208
|
-
g_static_mdtab_maxprobe = j;
|
209
|
-
}
|
210
|
-
}
|
211
126
|
/* initialize shards */
|
212
|
-
for (i = 0; i <
|
213
|
-
|
214
|
-
gpr_mu_init(&shard->mu);
|
215
|
-
shard->count = 0;
|
216
|
-
shard->capacity = INITIAL_STRTAB_CAPACITY;
|
217
|
-
shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity);
|
218
|
-
memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity);
|
219
|
-
}
|
220
|
-
for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
|
221
|
-
mdtab_shard *shard = &g_mdtab_shard[i];
|
127
|
+
for (size_t i = 0; i < SHARD_COUNT; i++) {
|
128
|
+
mdtab_shard *shard = &g_shards[i];
|
222
129
|
gpr_mu_init(&shard->mu);
|
223
130
|
shard->count = 0;
|
224
131
|
gpr_atm_no_barrier_store(&shard->free_estimate, 0);
|
225
|
-
shard->capacity =
|
226
|
-
shard->elems =
|
227
|
-
memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
|
132
|
+
shard->capacity = INITIAL_SHARD_CAPACITY;
|
133
|
+
shard->elems = gpr_zalloc(sizeof(*shard->elems) * shard->capacity);
|
228
134
|
}
|
229
135
|
}
|
230
136
|
|
231
137
|
void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
|
232
|
-
size_t i;
|
233
|
-
|
234
|
-
mdtab_shard *shard = &g_mdtab_shard[i];
|
138
|
+
for (size_t i = 0; i < SHARD_COUNT; i++) {
|
139
|
+
mdtab_shard *shard = &g_shards[i];
|
235
140
|
gpr_mu_destroy(&shard->mu);
|
236
141
|
gc_mdtab(exec_ctx, shard);
|
237
142
|
/* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
|
@@ -244,212 +149,35 @@ void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
|
|
244
149
|
}
|
245
150
|
gpr_free(shard->elems);
|
246
151
|
}
|
247
|
-
for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
|
248
|
-
strtab_shard *shard = &g_strtab_shard[i];
|
249
|
-
gpr_mu_destroy(&shard->mu);
|
250
|
-
/* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
|
251
|
-
if (shard->count != 0) {
|
252
|
-
gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
|
253
|
-
shard->count);
|
254
|
-
for (size_t j = 0; j < shard->capacity; j++) {
|
255
|
-
for (internal_string *s = shard->strs[j]; s; s = s->bucket_next) {
|
256
|
-
gpr_log(GPR_DEBUG, "LEAKED: %s",
|
257
|
-
grpc_mdstr_as_c_string((grpc_mdstr *)s));
|
258
|
-
}
|
259
|
-
}
|
260
|
-
if (grpc_iomgr_abort_on_leaks()) {
|
261
|
-
abort();
|
262
|
-
}
|
263
|
-
}
|
264
|
-
gpr_free(shard->strs);
|
265
|
-
}
|
266
152
|
}
|
267
153
|
|
268
|
-
static int
|
269
|
-
return
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
static int is_mdelem_static(grpc_mdelem *e) {
|
274
|
-
return e >= &grpc_static_mdelem_table[0] &&
|
275
|
-
e < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
|
154
|
+
static int is_mdelem_static(grpc_mdelem e) {
|
155
|
+
return GRPC_MDELEM_DATA(e) >= &grpc_static_mdelem_table[0] &&
|
156
|
+
GRPC_MDELEM_DATA(e) <
|
157
|
+
&grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
|
276
158
|
}
|
277
159
|
|
278
160
|
static void ref_md_locked(mdtab_shard *shard,
|
279
|
-
|
161
|
+
interned_metadata *md DEBUG_ARGS) {
|
280
162
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
163
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
164
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
281
165
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
282
166
|
"ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
|
283
167
|
gpr_atm_no_barrier_load(&md->refcnt),
|
284
|
-
gpr_atm_no_barrier_load(&md->refcnt) + 1,
|
285
|
-
|
286
|
-
|
168
|
+
gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
|
169
|
+
gpr_free(key_str);
|
170
|
+
gpr_free(value_str);
|
287
171
|
#endif
|
288
172
|
if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
|
289
173
|
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
|
290
174
|
}
|
291
175
|
}
|
292
176
|
|
293
|
-
static void grow_strtab(strtab_shard *shard) {
|
294
|
-
size_t capacity = shard->capacity * 2;
|
295
|
-
size_t i;
|
296
|
-
internal_string **strtab;
|
297
|
-
internal_string *s, *next;
|
298
|
-
|
299
|
-
GPR_TIMER_BEGIN("grow_strtab", 0);
|
300
|
-
|
301
|
-
strtab = gpr_malloc(sizeof(internal_string *) * capacity);
|
302
|
-
memset(strtab, 0, sizeof(internal_string *) * capacity);
|
303
|
-
|
304
|
-
for (i = 0; i < shard->capacity; i++) {
|
305
|
-
for (s = shard->strs[i]; s; s = next) {
|
306
|
-
size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity);
|
307
|
-
next = s->bucket_next;
|
308
|
-
s->bucket_next = strtab[idx];
|
309
|
-
strtab[idx] = s;
|
310
|
-
}
|
311
|
-
}
|
312
|
-
|
313
|
-
gpr_free(shard->strs);
|
314
|
-
shard->strs = strtab;
|
315
|
-
shard->capacity = capacity;
|
316
|
-
|
317
|
-
GPR_TIMER_END("grow_strtab", 0);
|
318
|
-
}
|
319
|
-
|
320
|
-
static void internal_destroy_string(grpc_exec_ctx *exec_ctx,
|
321
|
-
strtab_shard *shard, internal_string *is) {
|
322
|
-
internal_string **prev_next;
|
323
|
-
internal_string *cur;
|
324
|
-
GPR_TIMER_BEGIN("internal_destroy_string", 0);
|
325
|
-
if (is->has_base64_and_huffman_encoded) {
|
326
|
-
grpc_slice_unref_internal(exec_ctx, is->base64_and_huffman);
|
327
|
-
}
|
328
|
-
for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT,
|
329
|
-
shard->capacity)],
|
330
|
-
cur = *prev_next;
|
331
|
-
cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next)
|
332
|
-
;
|
333
|
-
*prev_next = cur->bucket_next;
|
334
|
-
shard->count--;
|
335
|
-
gpr_free(is);
|
336
|
-
GPR_TIMER_END("internal_destroy_string", 0);
|
337
|
-
}
|
338
|
-
|
339
|
-
static void slice_ref(void *p) {
|
340
|
-
internal_string *is =
|
341
|
-
(internal_string *)((char *)p - offsetof(internal_string, refcount));
|
342
|
-
GRPC_MDSTR_REF((grpc_mdstr *)(is));
|
343
|
-
}
|
344
|
-
|
345
|
-
static void slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
|
346
|
-
internal_string *is =
|
347
|
-
(internal_string *)((char *)p - offsetof(internal_string, refcount));
|
348
|
-
GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)(is));
|
349
|
-
}
|
350
|
-
|
351
|
-
grpc_mdstr *grpc_mdstr_from_string(const char *str) {
|
352
|
-
return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str));
|
353
|
-
}
|
354
|
-
|
355
|
-
grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
|
356
|
-
grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice),
|
357
|
-
GRPC_SLICE_LENGTH(slice));
|
358
|
-
grpc_slice_unref_internal(exec_ctx, slice);
|
359
|
-
return result;
|
360
|
-
}
|
361
|
-
|
362
|
-
grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
|
363
|
-
uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed);
|
364
|
-
internal_string *s;
|
365
|
-
strtab_shard *shard =
|
366
|
-
&g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)];
|
367
|
-
size_t i;
|
368
|
-
size_t idx;
|
369
|
-
|
370
|
-
GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0);
|
371
|
-
|
372
|
-
/* search for a static string */
|
373
|
-
for (i = 0; i <= g_static_strtab_maxprobe; i++) {
|
374
|
-
grpc_mdstr *ss;
|
375
|
-
idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab);
|
376
|
-
ss = g_static_strtab[idx];
|
377
|
-
if (ss == NULL) break;
|
378
|
-
if (ss->hash == hash && GRPC_SLICE_LENGTH(ss->slice) == length &&
|
379
|
-
(length == 0 ||
|
380
|
-
0 == memcmp(buf, GRPC_SLICE_START_PTR(ss->slice), length))) {
|
381
|
-
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
|
382
|
-
return ss;
|
383
|
-
}
|
384
|
-
}
|
385
|
-
|
386
|
-
gpr_mu_lock(&shard->mu);
|
387
|
-
|
388
|
-
/* search for an existing string */
|
389
|
-
idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity);
|
390
|
-
for (s = shard->strs[idx]; s; s = s->bucket_next) {
|
391
|
-
if (s->hash == hash && GRPC_SLICE_LENGTH(s->slice) == length &&
|
392
|
-
0 == memcmp(buf, GRPC_SLICE_START_PTR(s->slice), length)) {
|
393
|
-
if (gpr_atm_full_fetch_add(&s->refcnt, 1) == 0) {
|
394
|
-
/* If we get here, we've added a ref to something that was about to
|
395
|
-
* die - drop it immediately.
|
396
|
-
* The *only* possible path here (given the shard mutex) should be to
|
397
|
-
* drop from one ref back to zero - assert that with a CAS */
|
398
|
-
GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
|
399
|
-
/* and treat this as if we were never here... sshhh */
|
400
|
-
} else {
|
401
|
-
gpr_mu_unlock(&shard->mu);
|
402
|
-
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
|
403
|
-
return (grpc_mdstr *)s;
|
404
|
-
}
|
405
|
-
}
|
406
|
-
}
|
407
|
-
|
408
|
-
/* not found: create a new string */
|
409
|
-
if (length + 1 < GRPC_SLICE_INLINED_SIZE) {
|
410
|
-
/* string data goes directly into the slice */
|
411
|
-
s = gpr_malloc(sizeof(internal_string));
|
412
|
-
gpr_atm_rel_store(&s->refcnt, 1);
|
413
|
-
s->slice.refcount = NULL;
|
414
|
-
memcpy(s->slice.data.inlined.bytes, buf, length);
|
415
|
-
s->slice.data.inlined.bytes[length] = 0;
|
416
|
-
s->slice.data.inlined.length = (uint8_t)length;
|
417
|
-
} else {
|
418
|
-
/* string data goes after the internal_string header, and we +1 for null
|
419
|
-
terminator */
|
420
|
-
s = gpr_malloc(sizeof(internal_string) + length + 1);
|
421
|
-
gpr_atm_rel_store(&s->refcnt, 1);
|
422
|
-
s->refcount.ref = slice_ref;
|
423
|
-
s->refcount.unref = slice_unref;
|
424
|
-
s->slice.refcount = &s->refcount;
|
425
|
-
s->slice.data.refcounted.bytes = (uint8_t *)(s + 1);
|
426
|
-
s->slice.data.refcounted.length = length;
|
427
|
-
memcpy(s->slice.data.refcounted.bytes, buf, length);
|
428
|
-
/* add a null terminator for cheap c string conversion when desired */
|
429
|
-
s->slice.data.refcounted.bytes[length] = 0;
|
430
|
-
}
|
431
|
-
s->has_base64_and_huffman_encoded = 0;
|
432
|
-
s->hash = hash;
|
433
|
-
s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET;
|
434
|
-
s->bucket_next = shard->strs[idx];
|
435
|
-
shard->strs[idx] = s;
|
436
|
-
|
437
|
-
shard->count++;
|
438
|
-
|
439
|
-
if (shard->count > shard->capacity * 2) {
|
440
|
-
grow_strtab(shard);
|
441
|
-
}
|
442
|
-
|
443
|
-
gpr_mu_unlock(&shard->mu);
|
444
|
-
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
|
445
|
-
|
446
|
-
return (grpc_mdstr *)s;
|
447
|
-
}
|
448
|
-
|
449
177
|
static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
|
450
178
|
size_t i;
|
451
|
-
|
452
|
-
|
179
|
+
interned_metadata **prev_next;
|
180
|
+
interned_metadata *md, *next;
|
453
181
|
gpr_atm num_freed = 0;
|
454
182
|
|
455
183
|
GPR_TIMER_BEGIN("gc_mdtab", 0);
|
@@ -459,8 +187,8 @@ static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
|
|
459
187
|
void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
|
460
188
|
next = md->bucket_next;
|
461
189
|
if (gpr_atm_acq_load(&md->refcnt) == 0) {
|
462
|
-
|
463
|
-
|
190
|
+
grpc_slice_unref_internal(exec_ctx, md->key);
|
191
|
+
grpc_slice_unref_internal(exec_ctx, md->value);
|
464
192
|
if (md->user_data) {
|
465
193
|
((destroy_user_data_func)gpr_atm_no_barrier_load(
|
466
194
|
&md->destroy_user_data))(user_data);
|
@@ -481,21 +209,21 @@ static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
|
|
481
209
|
static void grow_mdtab(mdtab_shard *shard) {
|
482
210
|
size_t capacity = shard->capacity * 2;
|
483
211
|
size_t i;
|
484
|
-
|
485
|
-
|
212
|
+
interned_metadata **mdtab;
|
213
|
+
interned_metadata *md, *next;
|
486
214
|
uint32_t hash;
|
487
215
|
|
488
216
|
GPR_TIMER_BEGIN("grow_mdtab", 0);
|
489
217
|
|
490
|
-
mdtab =
|
491
|
-
memset(mdtab, 0, sizeof(internal_metadata *) * capacity);
|
218
|
+
mdtab = gpr_zalloc(sizeof(interned_metadata *) * capacity);
|
492
219
|
|
493
220
|
for (i = 0; i < shard->capacity; i++) {
|
494
221
|
for (md = shard->elems[i]; md; md = next) {
|
495
222
|
size_t idx;
|
496
|
-
hash = GRPC_MDSTR_KV_HASH(md->key
|
223
|
+
hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
|
224
|
+
grpc_slice_hash(md->value));
|
497
225
|
next = md->bucket_next;
|
498
|
-
idx = TABLE_IDX(hash,
|
226
|
+
idx = TABLE_IDX(hash, capacity);
|
499
227
|
md->bucket_next = mdtab[idx];
|
500
228
|
mdtab[idx] = md;
|
501
229
|
}
|
@@ -517,62 +245,77 @@ static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
|
|
517
245
|
}
|
518
246
|
}
|
519
247
|
|
520
|
-
grpc_mdelem
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
size_t i;
|
529
|
-
size_t idx;
|
248
|
+
grpc_mdelem grpc_mdelem_create(
|
249
|
+
grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
|
250
|
+
grpc_mdelem_data *compatible_external_backing_store) {
|
251
|
+
if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
|
252
|
+
if (compatible_external_backing_store != NULL) {
|
253
|
+
return GRPC_MAKE_MDELEM(compatible_external_backing_store,
|
254
|
+
GRPC_MDELEM_STORAGE_EXTERNAL);
|
255
|
+
}
|
530
256
|
|
531
|
-
|
257
|
+
allocated_metadata *allocated = gpr_malloc(sizeof(*allocated));
|
258
|
+
allocated->key = grpc_slice_ref_internal(key);
|
259
|
+
allocated->value = grpc_slice_ref_internal(value);
|
260
|
+
gpr_atm_rel_store(&allocated->refcnt, 1);
|
261
|
+
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
262
|
+
char *key_str = grpc_slice_to_c_string(allocated->key);
|
263
|
+
char *value_str = grpc_slice_to_c_string(allocated->value);
|
264
|
+
gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%zu: '%s' = '%s'", (void *)allocated,
|
265
|
+
gpr_atm_no_barrier_load(&allocated->refcnt), key_str, value_str);
|
266
|
+
gpr_free(key_str);
|
267
|
+
gpr_free(value_str);
|
268
|
+
#endif
|
269
|
+
return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED);
|
270
|
+
}
|
532
271
|
|
533
|
-
if (
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
if (smd->key == mkey && smd->value == mvalue) {
|
540
|
-
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
|
541
|
-
return smd;
|
542
|
-
}
|
272
|
+
if (GRPC_IS_STATIC_METADATA_STRING(key) &&
|
273
|
+
GRPC_IS_STATIC_METADATA_STRING(value)) {
|
274
|
+
grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings(
|
275
|
+
GRPC_STATIC_METADATA_INDEX(key), GRPC_STATIC_METADATA_INDEX(value));
|
276
|
+
if (!GRPC_MDISNULL(static_elem)) {
|
277
|
+
return static_elem;
|
543
278
|
}
|
544
279
|
}
|
545
280
|
|
281
|
+
uint32_t hash =
|
282
|
+
GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value));
|
283
|
+
interned_metadata *md;
|
284
|
+
mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
|
285
|
+
size_t idx;
|
286
|
+
|
287
|
+
GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
|
288
|
+
|
546
289
|
gpr_mu_lock(&shard->mu);
|
547
290
|
|
548
|
-
idx = TABLE_IDX(hash,
|
291
|
+
idx = TABLE_IDX(hash, shard->capacity);
|
549
292
|
/* search for an existing pair */
|
550
293
|
for (md = shard->elems[idx]; md; md = md->bucket_next) {
|
551
|
-
if (md->key
|
294
|
+
if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) {
|
552
295
|
REF_MD_LOCKED(shard, md);
|
553
|
-
GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)key);
|
554
|
-
GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)value);
|
555
296
|
gpr_mu_unlock(&shard->mu);
|
556
297
|
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
|
557
|
-
return (
|
298
|
+
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
|
558
299
|
}
|
559
300
|
}
|
560
301
|
|
561
302
|
/* not found: create a new pair */
|
562
|
-
md = gpr_malloc(sizeof(
|
303
|
+
md = gpr_malloc(sizeof(interned_metadata));
|
563
304
|
gpr_atm_rel_store(&md->refcnt, 1);
|
564
|
-
md->key = key;
|
565
|
-
md->value = value;
|
305
|
+
md->key = grpc_slice_ref_internal(key);
|
306
|
+
md->value = grpc_slice_ref_internal(value);
|
566
307
|
md->user_data = 0;
|
567
308
|
md->destroy_user_data = 0;
|
568
309
|
md->bucket_next = shard->elems[idx];
|
569
310
|
shard->elems[idx] = md;
|
570
311
|
gpr_mu_init(&md->mu_user_data);
|
571
312
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
313
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
314
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
572
315
|
gpr_log(GPR_DEBUG, "ELM NEW:%p:%zu: '%s' = '%s'", (void *)md,
|
573
|
-
gpr_atm_no_barrier_load(&md->refcnt),
|
574
|
-
|
575
|
-
|
316
|
+
gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str);
|
317
|
+
gpr_free(key_str);
|
318
|
+
gpr_free(value_str);
|
576
319
|
#endif
|
577
320
|
shard->count++;
|
578
321
|
|
@@ -584,29 +327,26 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
|
|
584
327
|
|
585
328
|
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
|
586
329
|
|
587
|
-
return (
|
588
|
-
}
|
589
|
-
|
590
|
-
grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
|
591
|
-
const char *value) {
|
592
|
-
return grpc_mdelem_from_metadata_strings(
|
593
|
-
exec_ctx, grpc_mdstr_from_string(key), grpc_mdstr_from_string(value));
|
330
|
+
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
|
594
331
|
}
|
595
332
|
|
596
|
-
grpc_mdelem
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
333
|
+
grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
|
334
|
+
grpc_slice value) {
|
335
|
+
grpc_mdelem out = grpc_mdelem_create(exec_ctx, key, value, NULL);
|
336
|
+
grpc_slice_unref_internal(exec_ctx, key);
|
337
|
+
grpc_slice_unref_internal(exec_ctx, value);
|
338
|
+
return out;
|
601
339
|
}
|
602
340
|
|
603
|
-
grpc_mdelem
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
341
|
+
grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
|
342
|
+
grpc_metadata *metadata) {
|
343
|
+
bool changed = false;
|
344
|
+
grpc_slice key_slice =
|
345
|
+
grpc_slice_maybe_static_intern(metadata->key, &changed);
|
346
|
+
grpc_slice value_slice =
|
347
|
+
grpc_slice_maybe_static_intern(metadata->value, &changed);
|
348
|
+
return grpc_mdelem_create(exec_ctx, key_slice, value_slice,
|
349
|
+
changed ? NULL : (grpc_mdelem_data *)metadata);
|
610
350
|
}
|
611
351
|
|
612
352
|
static size_t get_base64_encoded_size(size_t raw_length) {
|
@@ -614,160 +354,176 @@ static size_t get_base64_encoded_size(size_t raw_length) {
|
|
614
354
|
return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
|
615
355
|
}
|
616
356
|
|
617
|
-
size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem
|
618
|
-
size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(elem
|
619
|
-
size_t value_len = GRPC_SLICE_LENGTH(elem
|
620
|
-
if (
|
621
|
-
|
622
|
-
(const char *)GRPC_SLICE_START_PTR(elem->key->slice),
|
623
|
-
GRPC_SLICE_LENGTH(elem->key->slice))) {
|
624
|
-
return overhead_and_key + get_base64_encoded_size(value_len);
|
625
|
-
} else {
|
626
|
-
return overhead_and_key + value_len;
|
627
|
-
}
|
357
|
+
size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem) {
|
358
|
+
size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
|
359
|
+
size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
|
360
|
+
if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
|
361
|
+
return overhead_and_key + get_base64_encoded_size(value_len);
|
628
362
|
} else {
|
629
|
-
|
630
|
-
gpr_atm current_size = gpr_atm_acq_load(&is->size_in_decoder_table);
|
631
|
-
if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) {
|
632
|
-
if (grpc_is_binary_header(
|
633
|
-
(const char *)GRPC_SLICE_START_PTR(elem->key->slice),
|
634
|
-
GRPC_SLICE_LENGTH(elem->key->slice))) {
|
635
|
-
current_size = (gpr_atm)get_base64_encoded_size(value_len);
|
636
|
-
} else {
|
637
|
-
current_size = (gpr_atm)value_len;
|
638
|
-
}
|
639
|
-
gpr_atm_rel_store(&is->size_in_decoder_table, current_size);
|
640
|
-
}
|
641
|
-
return overhead_and_key + (size_t)current_size;
|
363
|
+
return overhead_and_key + value_len;
|
642
364
|
}
|
643
365
|
}
|
644
366
|
|
645
|
-
grpc_mdelem
|
646
|
-
|
647
|
-
|
367
|
+
grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
|
368
|
+
switch (GRPC_MDELEM_STORAGE(gmd)) {
|
369
|
+
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
370
|
+
case GRPC_MDELEM_STORAGE_STATIC:
|
371
|
+
break;
|
372
|
+
case GRPC_MDELEM_STORAGE_INTERNED: {
|
373
|
+
interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
|
648
374
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
375
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
376
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
377
|
+
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
378
|
+
"ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
|
379
|
+
gpr_atm_no_barrier_load(&md->refcnt),
|
380
|
+
gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
|
381
|
+
gpr_free(key_str);
|
382
|
+
gpr_free(value_str);
|
655
383
|
#endif
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
}
|
664
|
-
|
665
|
-
|
666
|
-
internal_metadata *md = (internal_metadata *)gmd;
|
667
|
-
if (!md) return;
|
668
|
-
if (is_mdelem_static(gmd)) return;
|
384
|
+
/* we can assume the ref count is >= 1 as the application is calling
|
385
|
+
this function - meaning that no adjustment to mdtab_free is necessary,
|
386
|
+
simplifying the logic here to be just an atomic increment */
|
387
|
+
/* use C assert to have this removed in opt builds */
|
388
|
+
GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
|
389
|
+
gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
|
390
|
+
break;
|
391
|
+
}
|
392
|
+
case GRPC_MDELEM_STORAGE_ALLOCATED: {
|
393
|
+
allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
|
669
394
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
395
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
396
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
397
|
+
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
398
|
+
"ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
|
399
|
+
gpr_atm_no_barrier_load(&md->refcnt),
|
400
|
+
gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
|
401
|
+
gpr_free(key_str);
|
402
|
+
gpr_free(value_str);
|
676
403
|
#endif
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
&g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
|
685
|
-
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
|
404
|
+
/* we can assume the ref count is >= 1 as the application is calling
|
405
|
+
this function - meaning that no adjustment to mdtab_free is necessary,
|
406
|
+
simplifying the logic here to be just an atomic increment */
|
407
|
+
/* use C assert to have this removed in opt builds */
|
408
|
+
gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
|
409
|
+
break;
|
410
|
+
}
|
686
411
|
}
|
412
|
+
return gmd;
|
687
413
|
}
|
688
414
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
internal_string *s = (internal_string *)gs;
|
697
|
-
if (is_mdstr_static(gs)) return gs;
|
415
|
+
void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem gmd DEBUG_ARGS) {
|
416
|
+
switch (GRPC_MDELEM_STORAGE(gmd)) {
|
417
|
+
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
418
|
+
case GRPC_MDELEM_STORAGE_STATIC:
|
419
|
+
break;
|
420
|
+
case GRPC_MDELEM_STORAGE_INTERNED: {
|
421
|
+
interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
|
698
422
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
699
|
-
|
700
|
-
|
701
|
-
|
423
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
424
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
425
|
+
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
426
|
+
"ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
|
427
|
+
gpr_atm_no_barrier_load(&md->refcnt),
|
428
|
+
gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
|
429
|
+
gpr_free(key_str);
|
430
|
+
gpr_free(value_str);
|
702
431
|
#endif
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
432
|
+
uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
|
433
|
+
grpc_slice_hash(md->value));
|
434
|
+
const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
|
435
|
+
GPR_ASSERT(prev_refcount >= 1);
|
436
|
+
if (1 == prev_refcount) {
|
437
|
+
/* once the refcount hits zero, some other thread can come along and
|
438
|
+
free md at any time: it's unsafe from this point on to access it */
|
439
|
+
mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
|
440
|
+
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
|
441
|
+
}
|
442
|
+
break;
|
443
|
+
}
|
444
|
+
case GRPC_MDELEM_STORAGE_ALLOCATED: {
|
445
|
+
allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
|
710
446
|
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
|
711
|
-
|
712
|
-
|
713
|
-
|
447
|
+
char *key_str = grpc_slice_to_c_string(md->key);
|
448
|
+
char *value_str = grpc_slice_to_c_string(md->value);
|
449
|
+
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
450
|
+
"ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
|
451
|
+
gpr_atm_no_barrier_load(&md->refcnt),
|
452
|
+
gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
|
453
|
+
gpr_free(key_str);
|
454
|
+
gpr_free(value_str);
|
714
455
|
#endif
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
456
|
+
const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
|
457
|
+
GPR_ASSERT(prev_refcount >= 1);
|
458
|
+
if (1 == prev_refcount) {
|
459
|
+
grpc_slice_unref_internal(exec_ctx, md->key);
|
460
|
+
grpc_slice_unref_internal(exec_ctx, md->value);
|
461
|
+
gpr_free(md);
|
462
|
+
}
|
463
|
+
break;
|
464
|
+
}
|
722
465
|
}
|
723
466
|
}
|
724
467
|
|
725
|
-
void *grpc_mdelem_get_user_data(grpc_mdelem
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
468
|
+
void *grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void *)) {
|
469
|
+
switch (GRPC_MDELEM_STORAGE(md)) {
|
470
|
+
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
471
|
+
case GRPC_MDELEM_STORAGE_ALLOCATED:
|
472
|
+
return NULL;
|
473
|
+
case GRPC_MDELEM_STORAGE_STATIC:
|
474
|
+
return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
|
475
|
+
grpc_static_mdelem_table];
|
476
|
+
case GRPC_MDELEM_STORAGE_INTERNED: {
|
477
|
+
interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
|
478
|
+
void *result;
|
479
|
+
if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) {
|
480
|
+
return (void *)gpr_atm_no_barrier_load(&im->user_data);
|
481
|
+
} else {
|
482
|
+
return NULL;
|
483
|
+
}
|
484
|
+
return result;
|
485
|
+
}
|
735
486
|
}
|
736
|
-
return
|
487
|
+
GPR_UNREACHABLE_CODE(return NULL);
|
737
488
|
}
|
738
489
|
|
739
|
-
void *grpc_mdelem_set_user_data(grpc_mdelem
|
490
|
+
void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
|
740
491
|
void *user_data) {
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
gpr_mu_lock(&im->mu_user_data);
|
745
|
-
if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
|
746
|
-
/* user data can only be set once */
|
747
|
-
gpr_mu_unlock(&im->mu_user_data);
|
748
|
-
if (destroy_func != NULL) {
|
492
|
+
switch (GRPC_MDELEM_STORAGE(md)) {
|
493
|
+
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
494
|
+
case GRPC_MDELEM_STORAGE_ALLOCATED:
|
749
495
|
destroy_func(user_data);
|
496
|
+
return NULL;
|
497
|
+
case GRPC_MDELEM_STORAGE_STATIC:
|
498
|
+
destroy_func(user_data);
|
499
|
+
return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
|
500
|
+
grpc_static_mdelem_table];
|
501
|
+
case GRPC_MDELEM_STORAGE_INTERNED: {
|
502
|
+
interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
|
503
|
+
GPR_ASSERT(!is_mdelem_static(md));
|
504
|
+
GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
|
505
|
+
gpr_mu_lock(&im->mu_user_data);
|
506
|
+
if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
|
507
|
+
/* user data can only be set once */
|
508
|
+
gpr_mu_unlock(&im->mu_user_data);
|
509
|
+
if (destroy_func != NULL) {
|
510
|
+
destroy_func(user_data);
|
511
|
+
}
|
512
|
+
return (void *)gpr_atm_no_barrier_load(&im->user_data);
|
513
|
+
}
|
514
|
+
gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
|
515
|
+
gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
|
516
|
+
gpr_mu_unlock(&im->mu_user_data);
|
517
|
+
return user_data;
|
750
518
|
}
|
751
|
-
return (void *)gpr_atm_no_barrier_load(&im->user_data);
|
752
519
|
}
|
753
|
-
|
754
|
-
gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
|
755
|
-
gpr_mu_unlock(&im->mu_user_data);
|
756
|
-
return user_data;
|
520
|
+
GPR_UNREACHABLE_CODE(return NULL);
|
757
521
|
}
|
758
522
|
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
if (!s->has_base64_and_huffman_encoded) {
|
766
|
-
s->base64_and_huffman =
|
767
|
-
grpc_chttp2_base64_encode_and_huffman_compress(s->slice);
|
768
|
-
s->has_base64_and_huffman_encoded = 1;
|
769
|
-
}
|
770
|
-
slice = s->base64_and_huffman;
|
771
|
-
gpr_mu_unlock(&shard->mu);
|
772
|
-
return slice;
|
523
|
+
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) {
|
524
|
+
if (a.payload == b.payload) return true;
|
525
|
+
if (GRPC_MDELEM_IS_INTERNED(a) && GRPC_MDELEM_IS_INTERNED(b)) return false;
|
526
|
+
if (GRPC_MDISNULL(a) || GRPC_MDISNULL(b)) return false;
|
527
|
+
return grpc_slice_eq(GRPC_MDKEY(a), GRPC_MDKEY(b)) &&
|
528
|
+
grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b));
|
773
529
|
}
|