diff options
author | Craig Tiller <craig.tiller@gmail.com> | 2015-03-03 07:44:27 -0800 |
---|---|---|
committer | Craig Tiller <craig.tiller@gmail.com> | 2015-03-03 07:44:27 -0800 |
commit | 01ea61e4823d9869090e18283409ac4447988cfc (patch) | |
tree | 5d599cb0357394abd48d6e549f5c0275e2a1b428 /src/core | |
parent | 7e0d99f72b5347b9266e4527ef3d6c27da2087b7 (diff) | |
parent | 0cfc638d1955ddea4146864db8a2e0294f609249 (diff) |
Merge github.com:grpc/grpc into credit
Conflicts:
build.json
src/cpp/client/credentials.cc
vsprojects/vs2013/grpc.vcxproj
vsprojects/vs2013/grpc.vcxproj.filters
vsprojects/vs2013/grpc_shared.vcxproj
vsprojects/vs2013/grpc_shared.vcxproj.filters
vsprojects/vs2013/grpc_unsecure.vcxproj
vsprojects/vs2013/grpc_unsecure.vcxproj.filters
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/channel/channel_stack.c | 2 | ||||
-rw-r--r-- | src/core/channel/channel_stack.h | 4 | ||||
-rw-r--r-- | src/core/channel/connected_channel.c | 4 | ||||
-rw-r--r-- | src/core/debug/trace.c | 65 | ||||
-rw-r--r-- | src/core/debug/trace.h | 22 | ||||
-rw-r--r-- | src/core/iomgr/iomgr_posix.c | 3 | ||||
-rw-r--r-- | src/core/iomgr/tcp_posix.c | 6 | ||||
-rw-r--r-- | src/core/iomgr/tcp_posix.h | 2 | ||||
-rw-r--r-- | src/core/security/secure_endpoint.c | 6 | ||||
-rw-r--r-- | src/core/security/secure_endpoint.h | 2 | ||||
-rw-r--r-- | src/core/surface/completion_queue.c | 7 | ||||
-rw-r--r-- | src/core/surface/init.c | 10 | ||||
-rw-r--r-- | src/core/surface/init.h | 39 | ||||
-rw-r--r-- | src/core/surface/init_secure.c | 42 | ||||
-rw-r--r-- | src/core/surface/init_unsecure.c | 37 | ||||
-rw-r--r-- | src/core/surface/surface_trace.c | 36 | ||||
-rw-r--r-- | src/core/surface/surface_trace.h | 4 | ||||
-rw-r--r-- | src/core/transport/chttp2/frame_settings.c | 3 | ||||
-rw-r--r-- | src/core/transport/chttp2_transport.c | 47 | ||||
-rw-r--r-- | src/core/transport/chttp2_transport.h | 2 | ||||
-rw-r--r-- | src/core/tsi/transport_security.c | 4 | ||||
-rw-r--r-- | src/core/tsi/transport_security_interface.h | 4 |
22 files changed, 277 insertions, 74 deletions
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c index 0382a7a2f3..21df9771ce 100644 --- a/src/core/channel/channel_stack.c +++ b/src/core/channel/channel_stack.c @@ -36,6 +36,8 @@ #include <stdlib.h> +int grpc_trace_channel = 0; + /* Memory layouts. Channel stack is laid out as: { diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h index c136f5c17c..ef1da7b33b 100644 --- a/src/core/channel/channel_stack.h +++ b/src/core/channel/channel_stack.h @@ -298,7 +298,9 @@ void grpc_call_element_recv_metadata(grpc_call_element *cur_elem, void grpc_call_element_send_cancel(grpc_call_element *cur_elem); void grpc_call_element_send_finish(grpc_call_element *cur_elem); +extern int grpc_trace_channel; + #define GRPC_CALL_LOG_OP(sev, elem, op) \ - if (grpc_trace_bits & GRPC_TRACE_CHANNEL) grpc_call_log_op(sev, elem, op) + if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) #endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c index fa18655164..62611e08f3 100644 --- a/src/core/channel/connected_channel.c +++ b/src/core/channel/connected_channel.c @@ -48,12 +48,12 @@ /* the protobuf library will (by default) start warning at 100megs */ #define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024) -typedef struct { +typedef struct connected_channel_channel_data { grpc_transport *transport; gpr_uint32 max_message_length; } channel_data; -typedef struct { +typedef struct connected_channel_call_data { grpc_call_element *elem; grpc_stream_op_buffer outgoing_sopb; diff --git a/src/core/debug/trace.c b/src/core/debug/trace.c index b8eb755bff..32c35e7fb3 100644 --- a/src/core/debug/trace.c +++ b/src/core/debug/trace.c @@ -39,8 +39,21 @@ #include <grpc/support/log.h> #include "src/core/support/env.h" -#if GRPC_ENABLE_TRACING -gpr_uint32 grpc_trace_bits = 0; +typedef struct tracer { + const char *name; + int *flag; + struct tracer *next; +} tracer; +static tracer *tracers; + +void grpc_register_tracer(const char *name, int *flag) { + tracer *t = gpr_malloc(sizeof(*t)); + t->name = name; + t->flag = flag; + t->next = tracers; + *flag = 0; + tracers = t; +} static void add(const char *beg, const char *end, char ***ss, size_t *ns) { size_t n = *ns; @@ -67,26 +80,26 @@ static void parse(const char *s) { char **strings = NULL; size_t nstrings = 0; size_t i; + tracer *t; split(s, &strings, &nstrings); - grpc_trace_bits = 0; - for (i = 0; i < nstrings; i++) { const char *s = strings[i]; - if (0 == strcmp(s, "surface")) { - grpc_trace_bits |= GRPC_TRACE_SURFACE; - } else if (0 == strcmp(s, "channel")) { - grpc_trace_bits |= GRPC_TRACE_CHANNEL; - } else if (0 == strcmp(s, "tcp")) { - grpc_trace_bits |= GRPC_TRACE_TCP; - } else if (0 == strcmp(s, "secure_endpoint")) { - grpc_trace_bits |= GRPC_TRACE_SECURE_ENDPOINT; - } else if (0 == strcmp(s, "http")) { - grpc_trace_bits |= GRPC_TRACE_HTTP; - } else if (0 == strcmp(s, "all")) { - grpc_trace_bits = -1; + if (0 == strcmp(s, "all")) { + for (t = tracers; t; t = t->next) { + *t->flag = 1; + } } else { - gpr_log(GPR_ERROR, "Unknown trace var: '%s'", s); + int found = 0; + for (t = tracers; t; t = t->next) { + if (0 == strcmp(s, t->name)) { + *t->flag = 1; + found = 1; + } + } + if (!found) { + gpr_log(GPR_ERROR, "Unknown trace var: '%s'", s); + } } } @@ -96,17 +109,15 @@ static void parse(const char *s) { gpr_free(strings); } -void grpc_init_trace_bits() { - char *e = gpr_getenv("GRPC_TRACE"); - if (e == NULL) { - grpc_trace_bits = 0; - } else { +void grpc_tracer_init(const char *env_var) { + char *e = gpr_getenv(env_var); + if (e != NULL) { parse(e); gpr_free(e); } + while (tracers) { + tracer *t = tracers; + tracers = t->next; + gpr_free(t); + } } -#else -void grpc_init_trace_bits() { -} -#endif - diff --git a/src/core/debug/trace.h b/src/core/debug/trace.h index 2059599a7d..c02f14b7f2 100644 --- a/src/core/debug/trace.h +++ b/src/core/debug/trace.h @@ -36,25 +36,7 @@ #include <grpc/support/port_platform.h> -/* set to zero to remove all debug trace code */ -#ifndef GRPC_ENABLE_TRACING -# define GRPC_ENABLE_TRACING 1 -#endif - -typedef enum { - GRPC_TRACE_SURFACE = 1 << 0, - GRPC_TRACE_CHANNEL = 1 << 1, - GRPC_TRACE_TCP = 1 << 2, - GRPC_TRACE_SECURE_ENDPOINT = 1 << 3, - GRPC_TRACE_HTTP = 1 << 4 -} grpc_trace_bit_value; - -#if GRPC_ENABLE_TRACING -extern gpr_uint32 grpc_trace_bits; -#else -# define grpc_trace_bits 0 -#endif - -void grpc_init_trace_bits(); +void grpc_register_tracer(const char *name, int *flag); +void grpc_tracer_init(const char *env_var_name); #endif /* GRPC_INTERNAL_CORE_DEBUG_TRACE_H */ diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c index 14e3d182f6..758ae77b86 100644 --- a/src/core/iomgr/iomgr_posix.c +++ b/src/core/iomgr/iomgr_posix.c @@ -36,11 +36,14 @@ #ifdef GPR_POSIX_SOCKET #include "src/core/iomgr/iomgr_posix.h" +#include "src/core/debug/trace.h" #include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/tcp_posix.h" void grpc_iomgr_platform_init(void) { grpc_fd_global_init(); grpc_pollset_global_init(); + grpc_register_tracer("tcp", &grpc_tcp_trace); } void grpc_iomgr_platform_shutdown(void) { diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c index eceb0feadb..597a2a62d3 100644 --- a/src/core/iomgr/tcp_posix.c +++ b/src/core/iomgr/tcp_posix.c @@ -63,6 +63,8 @@ typedef struct grpc_tcp_slice_state { int memory_owned; /* True if slices array is owned */ } grpc_tcp_slice_state; +int grpc_tcp_trace = 0; + static void slice_state_init(grpc_tcp_slice_state *state, gpr_slice *slices, size_t nslices, size_t valid_slices) { state->slices = slices; @@ -294,7 +296,7 @@ static void call_read_cb(grpc_tcp *tcp, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status status) { grpc_endpoint_read_cb cb = tcp->read_cb; - if (grpc_trace_bits & GRPC_TRACE_TCP) { + if (grpc_tcp_trace) { size_t i; gpr_log(GPR_DEBUG, "read: status=%d", status); for (i = 0; i < nslices; i++) { @@ -495,7 +497,7 @@ static grpc_endpoint_write_status grpc_tcp_write(grpc_endpoint *ep, grpc_tcp *tcp = (grpc_tcp *)ep; grpc_endpoint_write_status status; - if (grpc_trace_bits & GRPC_TRACE_TCP) { + if (grpc_tcp_trace) { size_t i; for (i = 0; i < nslices; i++) { diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h index 7e8064bffc..44279d5a26 100644 --- a/src/core/iomgr/tcp_posix.h +++ b/src/core/iomgr/tcp_posix.h @@ -49,6 +49,8 @@ #define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192 +extern int grpc_tcp_trace; + /* Create a tcp endpoint given a file desciptor and a read slice size. Takes ownership of fd. */ grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size); diff --git a/src/core/security/secure_endpoint.c b/src/core/security/secure_endpoint.c index d6bdf5a709..7bb1de4413 100644 --- a/src/core/security/secure_endpoint.c +++ b/src/core/security/secure_endpoint.c @@ -65,6 +65,8 @@ typedef struct { gpr_refcount ref; } secure_endpoint; +int grpc_trace_secure_endpoint = 0; + static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); } static void destroy(secure_endpoint *secure_ep) { @@ -96,7 +98,7 @@ static void flush_read_staging_buffer(secure_endpoint *ep, gpr_uint8 **cur, static void call_read_cb(secure_endpoint *ep, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status error) { - if (grpc_trace_bits & GRPC_TRACE_SECURE_ENDPOINT) { + if (grpc_trace_secure_endpoint) { size_t i; for (i = 0; i < nslices; i++) { char *data = @@ -231,7 +233,7 @@ static grpc_endpoint_write_status endpoint_write(grpc_endpoint *secure_ep, grpc_endpoint_write_status status; GPR_ASSERT(ep->output_buffer.count == 0); - if (grpc_trace_bits & GRPC_TRACE_SECURE_ENDPOINT) { + if (grpc_trace_secure_endpoint) { for (i = 0; i < nslices; i++) { char *data = gpr_hexdump((char *)GPR_SLICE_START_PTR(slices[i]), diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h index 808889bf04..93c29b5111 100644 --- a/src/core/security/secure_endpoint.h +++ b/src/core/security/secure_endpoint.h @@ -39,6 +39,8 @@ struct tsi_frame_protector; +extern int grpc_trace_secure_endpoint; + /* Takes ownership of protector and to_wrap, and refs leftover_slices. */ grpc_endpoint *grpc_secure_endpoint_create( struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c index c4b8d60782..6a1d83ce5d 100644 --- a/src/core/surface/completion_queue.c +++ b/src/core/surface/completion_queue.c @@ -71,6 +71,7 @@ struct grpc_completion_queue { grpc_pollset pollset; /* 0 initially, 1 once we've begun shutting down */ int shutdown; + int shutdown_called; /* Head of a linked list of queued events (prev points to the last element) */ event *queue; /* Fixed size chained hash table of events for pluck() */ @@ -107,7 +108,6 @@ static event *add_locked(grpc_completion_queue *cc, grpc_completion_type type, grpc_event_finish_func on_finish, void *user_data) { event *ev = gpr_malloc(sizeof(event)); gpr_uintptr bucket = ((gpr_uintptr)tag) % NUM_TAG_BUCKETS; - GPR_ASSERT(!cc->shutdown); ev->base.type = type; ev->base.tag = tag; ev->base.call = call; @@ -150,6 +150,7 @@ static void end_op_locked(grpc_completion_queue *cc, #endif if (gpr_unref(&cc->refs)) { GPR_ASSERT(!cc->shutdown); + GPR_ASSERT(cc->shutdown_called); cc->shutdown = 1; gpr_cv_broadcast(GRPC_POLLSET_CV(&cc->pollset)); } @@ -380,6 +381,10 @@ grpc_event *grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, /* Shutdown simply drops a ref that we reserved at creation time; if we drop to zero here, then enter shutdown mode and wake up any waiters */ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { + gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset)); + cc->shutdown_called = 1; + gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset)); + if (gpr_unref(&cc->refs)) { gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset)); GPR_ASSERT(!cc->shutdown); diff --git a/src/core/surface/init.c b/src/core/surface/init.c index 2d8f36e9c2..4db66fb66e 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -35,6 +35,10 @@ #include "src/core/iomgr/iomgr.h" #include "src/core/debug/trace.h" #include "src/core/statistics/census_interface.h" +#include "src/core/channel/channel_stack.h" +#include "src/core/surface/init.h" +#include "src/core/surface/surface_trace.h" +#include "src/core/transport/chttp2_transport.h" static gpr_once g_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; @@ -50,7 +54,11 @@ void grpc_init(void) { gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { - grpc_init_trace_bits(); + grpc_register_tracer("channel", &grpc_trace_channel); + grpc_register_tracer("surface", &grpc_surface_trace); + grpc_register_tracer("http", &grpc_http_trace); + grpc_security_pre_init(); + grpc_tracer_init("GRPC_TRACE"); grpc_iomgr_init(); census_init(); } diff --git a/src/core/surface/init.h b/src/core/surface/init.h new file mode 100644 index 0000000000..ab40bedf87 --- /dev/null +++ b/src/core/surface/init.h @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_SURFACE_INIT_H +#define GRPC_INTERNAL_CORE_SURFACE_INIT_H + +void grpc_security_pre_init(void); + +#endif /* GRPC_INTERNAL_CORE_SURFACE_INIT_H */ diff --git a/src/core/surface/init_secure.c b/src/core/surface/init_secure.c new file mode 100644 index 0000000000..fa20e91583 --- /dev/null +++ b/src/core/surface/init_secure.c @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/surface/init.h" +#include "src/core/debug/trace.h" +#include "src/core/security/secure_endpoint.h" +#include "src/core/tsi/transport_security_interface.h" + +void grpc_security_pre_init(void) { + grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint); + grpc_register_tracer("transport_security", &tsi_tracing_enabled); +} diff --git a/src/core/surface/init_unsecure.c b/src/core/surface/init_unsecure.c new file mode 100644 index 0000000000..ddb70cef8e --- /dev/null +++ b/src/core/surface/init_unsecure.c @@ -0,0 +1,37 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/surface/init.h" + +void grpc_security_pre_init(void) { +} diff --git a/src/core/surface/surface_trace.c b/src/core/surface/surface_trace.c new file mode 100644 index 0000000000..57a0053162 --- /dev/null +++ b/src/core/surface/surface_trace.c @@ -0,0 +1,36 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/surface/surface_trace.h" + +int grpc_surface_trace = 0; diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h index 50071ee317..01302bb5d4 100644 --- a/src/core/surface/surface_trace.h +++ b/src/core/surface/surface_trace.h @@ -37,8 +37,10 @@ #include "src/core/debug/trace.h" #include <grpc/support/log.h> +extern int grpc_surface_trace; + #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ - if (grpc_trace_bits & GRPC_TRACE_SURFACE) { \ + if (grpc_surface_trace) { \ char *_ev = grpc_event_string(event); \ gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ gpr_free(_ev); \ diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c index e6c4b7e38f..8d3250c34f 100644 --- a/src/core/transport/chttp2/frame_settings.c +++ b/src/core/transport/chttp2/frame_settings.c @@ -37,6 +37,7 @@ #include "src/core/debug/trace.h" #include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/chttp2_transport.h" #include <grpc/support/log.h> #include <grpc/support/useful.h> @@ -218,7 +219,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( } } parser->incoming_settings[parser->id] = parser->value; - if (grpc_trace_bits & GRPC_TRACE_HTTP) { + if (grpc_http_trace) { gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id, parser->value); } diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 476cc4b226..0d01a37112 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -37,7 +37,6 @@ #include <stdio.h> #include <string.h> -#include "src/core/debug/trace.h" #include "src/core/support/string.h" #include "src/core/transport/chttp2/frame_data.h" #include "src/core/transport/chttp2/frame_goaway.h" @@ -64,11 +63,13 @@ #define CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" #define CLIENT_CONNECT_STRLEN 24 +int grpc_http_trace = 0; + typedef struct transport transport; typedef struct stream stream; #define IF_TRACING(stmt) \ - if (!(grpc_trace_bits & GRPC_TRACE_HTTP)) \ + if (!(grpc_http_trace)) \ ; \ else \ stmt @@ -309,6 +310,7 @@ static void push_setting(transport *t, grpc_chttp2_setting_id id, static int prepare_callbacks(transport *t); static void run_callbacks(transport *t, const grpc_transport_callbacks *cb); +static void call_cb_closed(transport *t, const grpc_transport_callbacks *cb); static int prepare_write(transport *t); static void perform_write(transport *t, grpc_endpoint *ep); @@ -516,13 +518,29 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup, static void destroy_transport(grpc_transport *gt) { transport *t = (transport *)gt; - gpr_mu_lock(&t->mu); + lock(t); t->destroying = 1; - while (t->calling_back) { + /* Wait for pending stuff to finish. + We need to be not calling back to ensure that closed() gets a chance to + trigger if needed during unlock() before we die. + We need to be not writing as cancellation finalization may produce some + callbacks that NEED to be made to close out some streams when t->writing + becomes 0. */ + while (t->calling_back || t->writing) { gpr_cv_wait(&t->cv, &t->mu, gpr_inf_future); } - t->cb = NULL; - gpr_mu_unlock(&t->mu); + drop_connection(t); + unlock(t); + + /* The drop_connection() above puts the transport into an error state, and + the follow-up unlock should then (as part of the cleanup work it does) + ensure that cb is NULL, and therefore not call back anything further. + This check validates this very subtle behavior. + It's shutdown path, so I don't believe an extra lock pair is going to be + problematic for performance. */ + lock(t); + GPR_ASSERT(!t->cb); + unlock(t); unref_transport(t); } @@ -680,6 +698,7 @@ static void stream_list_add_tail(transport *t, stream *s, stream_list_id id) { } static void stream_list_join(transport *t, stream *s, stream_list_id id) { + if (id == PENDING_CALLBACKS) GPR_ASSERT(t->cb != NULL || t->error_state == ERROR_STATE_NONE); if (s->included[id]) { return; } @@ -738,7 +757,7 @@ static void unlock(transport *t) { if (perform_callbacks) { t->calling_back = 1; } - if (t->error_state == ERROR_STATE_SEEN) { + if (t->error_state == ERROR_STATE_SEEN && !t->writing) { call_closed = 1; t->calling_back = 1; t->cb = NULL; /* no more callbacks */ @@ -772,7 +791,7 @@ static void unlock(transport *t) { } if (call_closed) { - cb->closed(t->cb_user_data, &t->base); + call_cb_closed(t, cb); } /* write some bytes if necessary */ @@ -903,13 +922,16 @@ static void finish_write_common(transport *t, int success) { } while ((s = stream_list_remove_head(t, WRITTEN_CLOSED))) { s->sent_write_closed = 1; - stream_list_join(t, s, PENDING_CALLBACKS); + if (!s->cancelled) stream_list_join(t, s, PENDING_CALLBACKS); } t->outbuf.count = 0; t->outbuf.length = 0; /* leave the writing flag up on shutdown to prevent further writes in unlock() from starting */ t->writing = 0; + if (t->destroying) { + gpr_cv_signal(&t->cv); + } if (!t->reading) { grpc_endpoint_destroy(t->ep); t->ep = NULL; @@ -979,7 +1001,8 @@ static void send_batch(grpc_transport *gt, grpc_stream *gs, grpc_stream_op *ops, } else { grpc_sopb_append(&t->nuke_later_sopb, ops, ops_count); } - if (is_last && s->outgoing_sopb.nops == 0 && s->read_closed) { + if (is_last && s->outgoing_sopb.nops == 0 && s->read_closed && + !s->published_close) { stream_list_join(t, s, PENDING_CALLBACKS); } @@ -1765,6 +1788,10 @@ static void run_callbacks(transport *t, const grpc_transport_callbacks *cb) { } } +static void call_cb_closed(transport *t, const grpc_transport_callbacks *cb) { + cb->closed(t->cb_user_data, &t->base); +} + static void add_to_pollset(grpc_transport *gt, grpc_pollset *pollset) { transport *t = (transport *)gt; lock(t); diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h index c5b65bd4f7..a7f1b9a864 100644 --- a/src/core/transport/chttp2_transport.h +++ b/src/core/transport/chttp2_transport.h @@ -37,6 +37,8 @@ #include "src/core/iomgr/endpoint.h" #include "src/core/transport/transport.h" +extern int grpc_http_trace; + void grpc_create_chttp2_transport(grpc_transport_setup_callback setup, void *arg, const grpc_channel_args *channel_args, diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index 04b30004fc..c8c74c5de5 100644 --- a/src/core/tsi/transport_security.c +++ b/src/core/tsi/transport_security.c @@ -40,10 +40,6 @@ int tsi_tracing_enabled = 0; -void tsi_enable_tracing() { - tsi_tracing_enabled = 1; -} - /* --- Utils. --- */ char* tsi_strdup(const char* src) { diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index 33a19bef0d..0edff54235 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -63,8 +63,8 @@ const char* tsi_result_to_string(tsi_result result); /* --- tsi tracing --- */ -/* Call this function before any other tsi function to avoid races. */ -void tsi_enable_tracing(void); +/* Set this early to avoid races */ +extern int tsi_tracing_enabled; /* --- tsi_frame_protector object --- |