mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-120974: Make _asyncio._leave_task atomic in the free-threaded build (#122139)
* gh-120974: Make _asyncio._leave_task atomic in the free-threaded build Update `_PyDict_DelItemIf` to allow for an argument to be passed to the predicate.
This commit is contained in:
parent
e6b25e9a09
commit
a15feded71
4 changed files with 49 additions and 46 deletions
|
@ -2508,7 +2508,7 @@ delete_index_from_values(PyDictValues *values, Py_ssize_t ix)
|
|||
values->size = size;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
|
||||
PyObject *old_value, uint64_t new_version)
|
||||
{
|
||||
|
@ -2550,7 +2550,6 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
|
|||
Py_DECREF(old_value);
|
||||
|
||||
ASSERT_CONSISTENT(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -2593,7 +2592,8 @@ delitem_knownhash_lock_held(PyObject *op, PyObject *key, Py_hash_t hash)
|
|||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
uint64_t new_version = _PyDict_NotifyEvent(
|
||||
interp, PyDict_EVENT_DELETED, mp, key, NULL);
|
||||
return delitem_common(mp, hash, ix, old_value, new_version);
|
||||
delitem_common(mp, hash, ix, old_value, new_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -2608,7 +2608,8 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
|
|||
|
||||
static int
|
||||
delitemif_lock_held(PyObject *op, PyObject *key,
|
||||
int (*predicate)(PyObject *value))
|
||||
int (*predicate)(PyObject *value, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
Py_ssize_t ix;
|
||||
PyDictObject *mp;
|
||||
|
@ -2618,24 +2619,20 @@ delitemif_lock_held(PyObject *op, PyObject *key,
|
|||
|
||||
ASSERT_DICT_LOCKED(op);
|
||||
|
||||
if (!PyDict_Check(op)) {
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
assert(key);
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
mp = (PyDictObject *)op;
|
||||
ix = _Py_dict_lookup(mp, key, hash, &old_value);
|
||||
if (ix == DKIX_ERROR)
|
||||
return -1;
|
||||
if (ix == DKIX_EMPTY || old_value == NULL) {
|
||||
_PyErr_SetKeyError(key);
|
||||
if (ix == DKIX_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (ix == DKIX_EMPTY || old_value == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = predicate(old_value);
|
||||
res = predicate(old_value, arg);
|
||||
if (res == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -2643,7 +2640,8 @@ delitemif_lock_held(PyObject *op, PyObject *key,
|
|||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
uint64_t new_version = _PyDict_NotifyEvent(
|
||||
interp, PyDict_EVENT_DELETED, mp, key, NULL);
|
||||
return delitem_common(mp, hash, ix, old_value, new_version);
|
||||
delitem_common(mp, hash, ix, old_value, new_version);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2655,11 +2653,13 @@ delitemif_lock_held(PyObject *op, PyObject *key,
|
|||
*/
|
||||
int
|
||||
_PyDict_DelItemIf(PyObject *op, PyObject *key,
|
||||
int (*predicate)(PyObject *value))
|
||||
int (*predicate)(PyObject *value, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
assert(PyDict_Check(op));
|
||||
int res;
|
||||
Py_BEGIN_CRITICAL_SECTION(op);
|
||||
res = delitemif_lock_held(op, key, predicate);
|
||||
res = delitemif_lock_held(op, key, predicate, arg);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue