Skip to content

Commit 3645754

Browse files
committed
fix lock-free list access on heapq
1 parent 504ae60 commit 3645754

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

Modules/_heapqmodule.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
5959
arr = _PyList_ITEMS(heap);
6060
parent = arr[parentpos];
6161
newitem = arr[pos];
62-
arr[parentpos] = newitem;
63-
arr[pos] = parent;
62+
_Py_atomic_store_ptr(&arr[parentpos], newitem);
63+
_Py_atomic_store_ptr(&arr[pos], parent);
6464
pos = parentpos;
6565
}
6666
return 0;
@@ -108,8 +108,8 @@ siftup(PyListObject *heap, Py_ssize_t pos)
108108
/* Move the smaller child up. */
109109
tmp1 = arr[childpos];
110110
tmp2 = arr[pos];
111-
arr[childpos] = tmp2;
112-
arr[pos] = tmp1;
111+
_Py_atomic_store_ptr(&arr[childpos], tmp2);
112+
_Py_atomic_store_ptr(&arr[pos], tmp1);
113113
pos = childpos;
114114
}
115115
/* Bubble it up to its final resting place (by sifting its parents down). */
@@ -172,8 +172,10 @@ heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
172172
if (!n)
173173
return lastelt;
174174
returnitem = PyList_GET_ITEM(heap, 0);
175-
PyList_SET_ITEM(heap, 0, lastelt);
176-
if (siftup_func((PyListObject *)heap, 0)) {
175+
// We're in the critical section now
176+
PyListObject *list = _PyList_CAST(heap);
177+
_Py_atomic_store_ptr(&list->ob_item[0], lastelt);
178+
if (siftup_func(list, 0)) {
177179
Py_DECREF(returnitem);
178180
return NULL;
179181
}

0 commit comments

Comments
 (0)