Skip to content

Commit 78a5d3a

Browse files
Make any remaining pending calls before shutdown.
1 parent 4000dcd commit 78a5d3a

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

Include/internal/pycore_ceval.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ extern "C" {
1111
#include "pycore_atomic.h"
1212
#include "pythread.h"
1313

14+
PyAPI_FUNC(int) _Py_MakePendingCalls(void);
15+
1416
struct _pending_calls {
1517
PyThread_type_lock lock;
1618
/* Request for running pending calls. */

Python/ceval.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,14 @@ make_pending_calls(void)
459459
return res;
460460
}
461461

462+
int
463+
_Py_MakePendingCalls(void)
464+
{
465+
assert(PyGILState_Check());
466+
467+
return make_pending_calls();
468+
}
469+
462470
/* Py_MakePendingCalls() is a simple wrapper for the sake
463471
of backward-compatibility. */
464472
int

Python/pylifecycle.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,8 +1462,20 @@ Py_EndInterpreter(PyThreadState *tstate)
14621462
Py_FatalError("Py_EndInterpreter: thread still has a frame");
14631463
interp->finalizing = 1;
14641464

1465+
// Wrap up existing threads.
14651466
wait_for_thread_shutdown();
14661467

1468+
// Make any remaining pending calls.
1469+
if (_Py_atomic_load_relaxed(&_PyRuntime.ceval.pending.calls_to_do)) {
1470+
if (_Py_MakePendingCalls() < 0) {
1471+
PyObject *exc, *val, *tb;
1472+
PyErr_Fetch(&exc, &val, &tb);
1473+
PyErr_BadInternalCall();
1474+
_PyErr_ChainExceptions(exc, val, tb);
1475+
PyErr_Print();
1476+
}
1477+
}
1478+
14671479
call_py_exitfuncs(interp);
14681480

14691481
if (tstate != interp->tstate_head || tstate->next != NULL)

0 commit comments

Comments
 (0)