From e699c47c1e39a7174ee603ec3f3e6ad3de197bf4 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 4 Dec 2018 14:28:58 -0800 Subject: [PATCH] credentials: call grpc_init/grpc_shutdown when created/destroyed This addresses https://github.com/grpc/grpc/issues/17001. Prior to https://github.com/grpc/grpc/pull/13603, our credentials cython objects used grpc_initi() and grpc_shutdown() on creation and destruction. These are now managed differently, but the grpc_init() and grpc_shutdown() calls are still required. See the MetadataCredentialsPluginWrapper in C++, which extends the GrpcLibraryCodegen class to ensure that grpc_init() and grpc_shutdown() are called appropriately. Without this, we can deadlock when a call to grpc.Channel#close() triggers grpc_shutdown() to block and wait for all timer threads to finish: one of these timer threads may end up unreffing the subchannel and triggering grpc_call_credentials_unref, which will jump back into Cython and hang when it tries to reacquire the GIL. --- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index ff523fb256c..6555e89edae 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -61,6 +61,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) + grpc_shutdown() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -76,6 +77,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials): c_metadata_plugin.state = self._metadata_plugin c_metadata_plugin.type = self._name cpython.Py_INCREF(self._metadata_plugin) + fork_handlers_and_grpc_init() return grpc_metadata_credentials_create_from_plugin(c_metadata_plugin, NULL)