From a01eeb47d7accb7378075e1128854f917292e6cf Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Mon, 12 Nov 2018 16:56:44 -0800 Subject: [PATCH] re-running tests, squashing commits --- config.m4 | 3 +- src/php/ext/grpc/channel.c | 2 + src/php/ext/grpc/channel.h | 3 + src/php/ext/grpc/php_grpc.c | 116 +++++++++++++++++++++++++++++++++++ templates/config.m4.template | 3 +- 5 files changed, 125 insertions(+), 2 deletions(-) diff --git a/config.m4 b/config.m4 index d0e22a8e438..fadae568ac8 100644 --- a/config.m4 +++ b/config.m4 @@ -664,7 +664,8 @@ if test "$PHP_GRPC" != "no"; then third_party/boringssl/third_party/fiat/curve25519.c \ , $ext_shared, , -fvisibility=hidden \ -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \ - -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0) + -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \ + -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1) PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index b17f3d9a613..c06bdea7feb 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -393,6 +393,8 @@ PHP_METHOD(Channel, __construct) { channel->wrapper->target = strdup(target); channel->wrapper->args_hashstr = strdup(sha1str); channel->wrapper->creds_hashstr = NULL; + channel->wrapper->creds = creds; + channel->wrapper->args = args; if (creds != NULL && creds->hashstr != NULL) { php_grpc_int creds_hashstr_len = strlen(creds->hashstr); char *channel_creds_hashstr = malloc(creds_hashstr_len + 1); diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index 27752c9a3f0..ce17c4a58a7 100644 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -19,6 +19,7 @@ #ifndef NET_GRPC_PHP_GRPC_CHANNEL_H_ #define NET_GRPC_PHP_GRPC_CHANNEL_H_ +#include "channel_credentials.h" #include "php_grpc.h" /* Class entry for the PHP Channel class */ @@ -32,6 +33,8 @@ typedef struct _grpc_channel_wrapper { char *creds_hashstr; size_t ref_count; gpr_mu mu; + grpc_channel_args args; + wrapped_grpc_channel_credentials *creds; } grpc_channel_wrapper; /* Wrapper struct for grpc_channel that can be associated with a PHP object */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index fabd98975df..89ee9f7f1f3 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -26,6 +26,8 @@ #include "call_credentials.h" #include "server_credentials.h" #include "completion_queue.h" +#include +#include ZEND_DECLARE_MODULE_GLOBALS(grpc) static PHP_GINIT_FUNCTION(grpc); @@ -86,6 +88,119 @@ ZEND_GET_MODULE(grpc) } */ /* }}} */ +void create_new_channel( + wrapped_grpc_channel *channel, + char *target, + grpc_channel_args args, + wrapped_grpc_channel_credentials *creds) { + if (creds == NULL) { + channel->wrapper->wrapped = grpc_insecure_channel_create(target, &args, + NULL); + } else { + channel->wrapper->wrapped = + grpc_secure_channel_create(creds->wrapped, target, &args, NULL); + } +} + +void acquire_persistent_locks() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + gpr_mu_lock(&le->channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void release_persistent_locks() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + gpr_mu_unlock(&le->channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void destroy_grpc_channels() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + wrapped_grpc_channel wrapped_channel; + wrapped_channel.wrapper = le->channel; + grpc_channel_wrapper *channel = wrapped_channel.wrapper; + grpc_channel_destroy(channel->wrapped); + PHP_GRPC_HASH_FOREACH_END() +} + +void restart_channels() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + wrapped_grpc_channel wrapped_channel; + wrapped_channel.wrapper = le->channel; + grpc_channel_wrapper *channel = wrapped_channel.wrapper; + create_new_channel(&wrapped_channel, channel->target, channel->args, + channel->creds); + gpr_mu_unlock(&channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void prefork() { + acquire_persistent_locks(); +} + +void postfork_child() { + // loop through persistant list and destroy all underlying grpc_channel objs + destroy_grpc_channels(); + + // clear completion queue + grpc_php_shutdown_completion_queue(); + + // clean-up grpc_core + grpc_shutdown(); + if (grpc_is_initialized() > 0) { + zend_throw_exception(spl_ce_UnexpectedValueException, + "Oops, failed to shutdown gRPC Core after fork()", + 1 TSRMLS_CC); + } + + // restart grpc_core + grpc_init(); + grpc_php_init_completion_queue(); + + // re-create grpc_channel and point wrapped to it + // unlock wrapped grpc channel mutex + restart_channels(); +} + +void postfork_parent() { + release_persistent_locks(); +} + +void register_fork_handlers() { + pthread_atfork(&prefork, &postfork_parent, &postfork_child); +} /* {{{ PHP_MINIT_FUNCTION */ @@ -265,6 +380,7 @@ PHP_MINFO_FUNCTION(grpc) { PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { grpc_init(); + register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); GRPC_G(initialized) = 1; } diff --git a/templates/config.m4.template b/templates/config.m4.template index 19f99049111..18378cfc34d 100644 --- a/templates/config.m4.template +++ b/templates/config.m4.template @@ -45,7 +45,8 @@ % endfor , $ext_shared, , -fvisibility=hidden ${"\\"} -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"} - -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0) + -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 ${"\\"} + -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1) PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) <%