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.
pull/17396/head
Eric Gribkoff 6 years ago
parent 1e1d4c2621
commit e699c47c1e
  1. 2
      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(<object>state)
grpc_shutdown()
cdef class MetadataPluginCallCredentials(CallCredentials):
@ -76,6 +77,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials):
c_metadata_plugin.state = <void *>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)

Loading…
Cancel
Save