Commit dbec7e74 authored by Jason Fried's avatar Jason Fried Committed by Facebook Github Bot

AsyncioExecutor should insure Python is not finalizing when calling drive in the dstor

Summary:
There have been weird edge cases we haven't tracked down yet that saw python segfaulting at shutdown, caused by drive() run from the destructor of AsyncioExecutor after Python had run Py_Finalize shutting down the runtime.

This fix uses new checks from Python >=3.7 to check if Python is finalizing

Reviewed By: yfeldblum, nanshu

Differential Revision: D19321677

fbshipit-source-id: 79a6f95df383a86d80e064eb55a8a81e29d50ace
parent 25c971b0
......@@ -16,12 +16,19 @@
#pragma once
#include <Python.h>
#include <folly/ExceptionString.h>
#include <folly/Function.h>
#include <folly/executors/DrivableExecutor.h>
#include <folly/executors/SequencedExecutor.h>
#include <folly/io/async/NotificationQueue.h>
#if PY_VERSION_HEX <= 0x03070000
#define FOLLY_DETAIL_PY_ISFINALIZING() false
#else
#define FOLLY_DETAIL_PY_ISFINALIZING() _Py_IsFinalizing()
#endif
namespace folly {
namespace python {
......@@ -31,8 +38,12 @@ class AsyncioExecutor : public DrivableExecutor, public SequencedExecutor {
~AsyncioExecutor() override {
keepAliveRelease();
while (keepAliveCounter_ > 0) {
drive();
if (!FOLLY_DETAIL_PY_ISFINALIZING()) {
// if Python is finalizing calling drive() WILL segfault.
// any code that could have been called is now inconsequential.
while (keepAliveCounter_ > 0) {
drive();
}
}
}
......
......@@ -36,6 +36,10 @@ cdef class AsyncioExecutor:
def __dealloc__(AsyncioExecutor self):
# We drive it one last time
deref(self.cQ).drive()
# We are Explicitly releasing here, otherwise it is possible
# that self.cQ dstor runs after python finalize
# Cython deletes these after __dealloc__ returns.
self.cQ.release()
cdef cAsyncioExecutor* get_executor():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment