Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3c03084

Browse filesBrowse files
committed
Don't use atomics for iteratio and allow multiple threads to race on values seen
1 parent 3618de1 commit 3c03084
Copy full SHA for 3c03084

File tree

1 file changed

+10
-23
lines changed
Filter options

1 file changed

+10
-23
lines changed

‎Objects/dictobject.c

Copy file name to clipboardExpand all lines: Objects/dictobject.c
+10-23Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4930,7 +4930,7 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self,
49304930

49314931
ensure_shared_on_read(d);
49324932

4933-
Py_ssize_t start_pos = i = _Py_atomic_load_ssize_relaxed(&di->di_pos);
4933+
i = _Py_atomic_load_ssize_relaxed(&di->di_pos);
49344934
k = _Py_atomic_load_ptr_relaxed(&d->ma_keys);
49354935
assert(i >= 0);
49364936
if (_PyDict_HasSplitTable(d)) {
@@ -4990,20 +4990,13 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self,
49904990
}
49914991
}
49924992
// We found an element (key), but did not expect it
4993-
if (_Py_atomic_load_ssize_relaxed(&di->len) == 0) {
4993+
Py_ssize_t len;
4994+
if ((len = _Py_atomic_load_ssize_relaxed(&di->len)) == 0) {
49944995
goto concurrent_modification;
49954996
}
4996-
if (!_Py_atomic_compare_exchange_ssize(&di->di_pos, &start_pos, i+1)) {
4997-
// We lost a race with someone else iterating...
4998-
if (out_key != NULL) {
4999-
Py_DECREF(*out_key);
5000-
}
5001-
if (out_value != NULL) {
5002-
Py_DECREF(*out_value);
5003-
}
5004-
goto try_locked;
5005-
}
5006-
_Py_atomic_add_ssize(&di->len, -1);
4997+
4998+
_Py_atomic_store_ssize_relaxed(&di->di_pos, i + 1);
4999+
_Py_atomic_store_ssize_relaxed(&di->len, len - 1);
50075000
return 1;
50085001

50095002
concurrent_modification:
@@ -5029,22 +5022,16 @@ static bool
50295022
acquire_iter_result(PyObject *result)
50305023
{
50315024
#ifdef Py_GIL_DISABLED
5032-
if (Py_REFCNT(result) == 1) {
5033-
Py_INCREF(result);
5034-
if (Py_REFCNT(result) == 2) {
5035-
return true;
5036-
}
5037-
Py_DECREF(result);
5038-
return false;
5039-
}
5040-
return false;
5025+
if (_Py_IsOwnedByCurrentThread(result) &&
5026+
result->ob_ref_local == 1 &&
5027+
_Py_atomic_load_ssize_relaxed(&result->ob_ref_shared) == 0) {
50415028
#else
50425029
if (Py_REFCNT(result) == 1) {
5030+
#endif
50435031
Py_INCREF(result);
50445032
return true;
50455033
}
50465034
return false;
5047-
#endif
50485035
}
50495036

50505037
static PyObject *

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.