aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.c57
-rw-r--r--src/core/lib/channel/handshaker.c37
-rw-r--r--src/core/lib/channel/handshaker.h16
-rw-r--r--src/core/lib/support/sync_posix.c10
4 files changed, 67 insertions, 53 deletions
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index ae2c3838ed..0fc180d52f 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -55,11 +55,6 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
-typedef struct pending_handshake_manager_node {
- grpc_handshake_manager *handshake_mgr;
- struct pending_handshake_manager_node *next;
-} pending_handshake_manager_node;
-
typedef struct {
grpc_server *server;
grpc_tcp_server *tcp_server;
@@ -68,7 +63,7 @@ typedef struct {
bool shutdown;
grpc_closure tcp_server_shutdown_complete;
grpc_closure *server_destroy_listener_done;
- pending_handshake_manager_node *pending_handshake_mgrs;
+ grpc_handshake_manager *pending_handshake_mgrs;
} server_state;
typedef struct {
@@ -78,44 +73,6 @@ typedef struct {
grpc_handshake_manager *handshake_mgr;
} server_connection_state;
-static void pending_handshake_manager_add_locked(
- server_state *state, grpc_handshake_manager *handshake_mgr) {
- pending_handshake_manager_node *node = gpr_malloc(sizeof(*node));
- node->handshake_mgr = handshake_mgr;
- node->next = state->pending_handshake_mgrs;
- state->pending_handshake_mgrs = node;
-}
-
-static void pending_handshake_manager_remove_locked(
- server_state *state, grpc_handshake_manager *handshake_mgr) {
- pending_handshake_manager_node **prev_node = &state->pending_handshake_mgrs;
- for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
- node != NULL; node = node->next) {
- if (node->handshake_mgr == handshake_mgr) {
- *prev_node = node->next;
- gpr_free(node);
- break;
- }
- prev_node = &node->next;
- }
-}
-
-static void pending_handshake_manager_shutdown_locked(grpc_exec_ctx *exec_ctx,
- server_state *state,
- grpc_error *why) {
- pending_handshake_manager_node *prev_node = NULL;
- for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
- node != NULL; node = node->next) {
- grpc_handshake_manager_shutdown(exec_ctx, node->handshake_mgr,
- GRPC_ERROR_REF(why));
- gpr_free(prev_node);
- prev_node = node;
- }
- gpr_free(prev_node);
- state->pending_handshake_mgrs = NULL;
- GRPC_ERROR_UNREF(why);
-}
-
static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_handshaker_args *args = arg;
@@ -153,8 +110,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
grpc_channel_args_destroy(exec_ctx, args->args);
}
}
- pending_handshake_manager_remove_locked(connection_state->server_state,
- connection_state->handshake_mgr);
+ grpc_handshake_manager_pending_list_remove(
+ &connection_state->server_state->pending_handshake_mgrs,
+ connection_state->handshake_mgr);
gpr_mu_unlock(&connection_state->server_state->mu);
grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp_server);
@@ -174,7 +132,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
return;
}
grpc_handshake_manager *handshake_mgr = grpc_handshake_manager_create();
- pending_handshake_manager_add_locked(state, handshake_mgr);
+ grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs,
+ handshake_mgr);
gpr_mu_unlock(&state->mu);
grpc_tcp_server_ref(state->tcp_server);
server_connection_state *connection_state =
@@ -213,8 +172,8 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_lock(&state->mu);
grpc_closure *destroy_done = state->server_destroy_listener_done;
GPR_ASSERT(state->shutdown);
- pending_handshake_manager_shutdown_locked(exec_ctx, state,
- GRPC_ERROR_REF(error));
+ grpc_handshake_manager_pending_list_shutdown_all(
+ exec_ctx, state->pending_handshake_mgrs, GRPC_ERROR_REF(error));
gpr_mu_unlock(&state->mu);
// Flush queued work before destroying handshaker factory, since that
// may do a synchronous unref.
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index 5bed2d041d..82c361c7ef 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -92,6 +92,10 @@ struct grpc_handshake_manager {
void* user_data;
// Handshaker args.
grpc_handshaker_args args;
+ // Links to the previous and next managers in a list of all pending handshakes
+ // Used at server side only.
+ grpc_handshake_manager* prev;
+ grpc_handshake_manager* next;
};
grpc_handshake_manager* grpc_handshake_manager_create() {
@@ -102,6 +106,39 @@ grpc_handshake_manager* grpc_handshake_manager_create() {
return mgr;
}
+void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head,
+ grpc_handshake_manager* mgr) {
+ GPR_ASSERT(mgr->prev == NULL);
+ GPR_ASSERT(mgr->next == NULL);
+ mgr->next = *head;
+ if (*head) {
+ (*head)->prev = mgr;
+ }
+ *head = mgr;
+}
+
+void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head,
+ grpc_handshake_manager* mgr) {
+ if (mgr->next != NULL) {
+ mgr->next->prev = mgr->prev;
+ }
+ if (mgr->prev != NULL) {
+ mgr->prev->next = mgr->next;
+ } else {
+ GPR_ASSERT(*head == mgr);
+ *head = mgr->next;
+ }
+}
+
+void grpc_handshake_manager_pending_list_shutdown_all(
+ grpc_exec_ctx* exec_ctx, grpc_handshake_manager* head, grpc_error* why) {
+ while (head != NULL) {
+ grpc_handshake_manager_shutdown(exec_ctx, head, GRPC_ERROR_REF(why));
+ head = head->next;
+ }
+ GRPC_ERROR_UNREF(why);
+}
+
static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; }
void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index a8e3692add..5f97c3fc73 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -163,4 +163,20 @@ void grpc_handshake_manager_do_handshake(
gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
grpc_iomgr_cb_func on_handshake_done, void* user_data);
+/// Add \a mgr to the server side list of all pending handshake managers, the
+/// list starts with \a *head.
+// Not thread-safe. Caller needs to synchronize.
+void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head,
+ grpc_handshake_manager* mgr);
+
+/// Remove \a mgr from the server side list of all pending handshake managers.
+// Not thread-safe. Caller needs to synchronize.
+void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head,
+ grpc_handshake_manager* mgr);
+
+/// Shutdown all pending handshake managers on the server side.
+// Not thread-safe. Caller needs to synchronize.
+void grpc_handshake_manager_pending_list_shutdown_all(
+ grpc_exec_ctx* exec_ctx, grpc_handshake_manager* head, grpc_error* why);
+
#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */
diff --git a/src/core/lib/support/sync_posix.c b/src/core/lib/support/sync_posix.c
index de0f0484b5..16e7d6e12a 100644
--- a/src/core/lib/support/sync_posix.c
+++ b/src/core/lib/support/sync_posix.c
@@ -42,8 +42,10 @@
#include <time.h>
#include "src/core/lib/profiling/timers.h"
-#ifdef GPR_MU_COUNTERS
-gpr_atm grpc_mu_locks = 0;
+#ifdef GPR_LOW_LEVEL_COUNTERS
+gpr_atm gpr_mu_locks = 0;
+gpr_atm gpr_counter_atm_cas = 0;
+gpr_atm gpr_counter_atm_add = 0;
#endif
void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); }
@@ -51,8 +53,8 @@ void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); }
void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
void gpr_mu_lock(gpr_mu* mu) {
-#ifdef GPR_MU_COUNTERS
- gpr_atm_no_barrier_fetch_add(&grpc_mu_locks, 1);
+#ifdef GPR_LOW_LEVEL_COUNTERS
+ GPR_ATM_INC_COUNTER(gpr_mu_locks);
#endif
GPR_TIMER_BEGIN("gpr_mu_lock", 0);
GPR_ASSERT(pthread_mutex_lock(mu) == 0);