[Python Fork] Use os.register_at_fork instead of pthread_atfork. (#32935)

Fix: https://github.com/grpc/grpc/issues/18075

From comments in https://github.com/grpc/grpc/issues/18075, `CPython`
reinitialize the `GIL` after `pthread_atfork` child handler, thus we
shouldn't use any `GIL` related functions in child handler which is what
we're currently doing, this PR uses `os.register_at_fork` to replace
`pthread_atfork` to prevent any undesired bevahior.

This also seems to fixes a thread hanging issue cased by changes in
core: https://github.com/grpc/grpc/pull/32869

### Testing:
* Passed existing fork tests. (Note that due to some issues in `Bazel`,
this change was not verified by `Bazel runs_per_test`).
* Tested by patch the core PR, was able to fix Python fork tests:
https://github.com/grpc/grpc/pull/32933
pull/32939/head
Xuan Wang 2 years ago committed by GitHub
parent 706352a86e
commit bcb97011f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi
  2. 5
      src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi

@ -12,14 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
cdef extern from "pthread.h" nogil:
int pthread_atfork(
void (*prepare)() nogil,
void (*parent)() nogil,
void (*child)() nogil)
cdef void __prefork() nogil

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
_AWAIT_THREADS_TIMEOUT_SECONDS = 5
@ -90,7 +91,9 @@ def fork_handlers_and_grpc_init():
if _GRPC_ENABLE_FORK_SUPPORT:
with _fork_state.fork_handler_registered_lock:
if not _fork_state.fork_handler_registered:
pthread_atfork(&__prefork, &__postfork_parent, &__postfork_child)
os.register_at_fork(before=__prefork,
after_in_parent=__postfork_parent,
after_in_child=__postfork_child)
_fork_state.fork_handler_registered = True

Loading…
Cancel
Save