mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-110693: Pending Calls Machinery Cleanups (gh-118296)
This does some cleanup in preparation for later changes.
This commit is contained in:
parent
d5df25268b
commit
09c2947581
7 changed files with 319 additions and 117 deletions
|
@ -1062,37 +1062,56 @@ static PyObject *
|
|||
pending_threadfunc(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *callable;
|
||||
unsigned int num = 1;
|
||||
int blocking = 0;
|
||||
int ensure_added = 0;
|
||||
static char *kwlist[] = {"", "ensure_added", NULL};
|
||||
static char *kwlist[] = {"callback", "num",
|
||||
"blocking", "ensure_added", NULL};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O|$p:pending_threadfunc", kwlist,
|
||||
&callable, &ensure_added))
|
||||
"O|I$pp:pending_threadfunc", kwlist,
|
||||
&callable, &num, &blocking, &ensure_added))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
|
||||
/* create the reference for the callbackwhile we hold the lock */
|
||||
Py_INCREF(callable);
|
||||
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
r = _PyEval_AddPendingCall(interp, &_pending_callback, callable, 0);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (r < 0) {
|
||||
/* unsuccessful add */
|
||||
if (!ensure_added) {
|
||||
Py_DECREF(callable);
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
r = _PyEval_AddPendingCall(interp, &_pending_callback, callable, 0);
|
||||
Py_END_ALLOW_THREADS
|
||||
} while (r < 0);
|
||||
for (unsigned int i = 0; i < num; i++) {
|
||||
Py_INCREF(callable);
|
||||
}
|
||||
|
||||
Py_RETURN_TRUE;
|
||||
PyThreadState *save_tstate = NULL;
|
||||
if (!blocking) {
|
||||
save_tstate = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
unsigned int num_added = 0;
|
||||
for (; num_added < num; num_added++) {
|
||||
if (ensure_added) {
|
||||
_Py_add_pending_call_result r;
|
||||
do {
|
||||
r = _PyEval_AddPendingCall(interp, &_pending_callback, callable, 0);
|
||||
assert(r == _Py_ADD_PENDING_SUCCESS
|
||||
|| r == _Py_ADD_PENDING_FULL);
|
||||
} while (r == _Py_ADD_PENDING_FULL);
|
||||
}
|
||||
else {
|
||||
if (_PyEval_AddPendingCall(interp, &_pending_callback, callable, 0) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!blocking) {
|
||||
PyEval_RestoreThread(save_tstate);
|
||||
}
|
||||
|
||||
for (unsigned int i = num_added; i < num; i++) {
|
||||
Py_DECREF(callable); /* unsuccessful add, destroy the extra reference */
|
||||
}
|
||||
|
||||
/* The callable is decref'ed in _pending_callback() above. */
|
||||
return PyLong_FromUnsignedLong((unsigned long)num_added);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1135,14 +1154,16 @@ pending_identify(PyObject *self, PyObject *args)
|
|||
PyThread_acquire_lock(mutex, WAIT_LOCK);
|
||||
/* It gets released in _pending_identify_callback(). */
|
||||
|
||||
int r;
|
||||
_Py_add_pending_call_result r;
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
r = _PyEval_AddPendingCall(interp,
|
||||
&_pending_identify_callback, (void *)mutex,
|
||||
0);
|
||||
Py_END_ALLOW_THREADS
|
||||
} while (r < 0);
|
||||
assert(r == _Py_ADD_PENDING_SUCCESS
|
||||
|| r == _Py_ADD_PENDING_FULL);
|
||||
} while (r == _Py_ADD_PENDING_FULL);
|
||||
|
||||
/* Wait for the pending call to complete. */
|
||||
PyThread_acquire_lock(mutex, WAIT_LOCK);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue