Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion multidict/_multilib/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
extern "C" {
#endif

#include <stdatomic.h>

/* State of the _multidict module */
typedef struct {
PyTypeObject *IStrType;
Expand Down Expand Up @@ -128,7 +130,7 @@ get_mod_state_by_def(PyObject *self)
static inline uint64_t
NEXT_VERSION(mod_state *state)
{
return ++state->global_version;
return atomic_fetch_add_explicit((_Atomic(uint64_t)*)&state->global_version, 1, memory_order_relaxed);
}

#ifdef __cplusplus
Expand Down
33 changes: 33 additions & 0 deletions tests/isolated/multidict_global_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import threading
import multidict

Check notice

Code scanning / CodeQL

Module is imported with 'import' and 'import from' Note test

Module 'multidict' is imported with both 'import' and 'import from'.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
bdraco marked this conversation as resolved.
Dismissed
from multidict import MultiDict
import sysconfig
Comment thread
Vizonex marked this conversation as resolved.
Outdated

FREETHREADED = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
if not FREETHREADED:
raise SystemExit(0)

md = MultiDict()
N, M = 3, 100
baseline = multidict.getversion(md)


def worker(tid):
for i in range(M):
md[f"k{tid}_{i}"] = i


if __name__ == "__main__":
threads = [threading.Thread(target=worker, args=(tid,)) for tid in range(N)]
for t in threads:
t.start()
for t in threads:
t.join()

observed = multidict.getversion(md) - baseline
expected = N * M
assert expected == observed, (
f"expected delta: {expected}"
f" observed: {observed} "
f"lost: {expected - observed}"
)
1 change: 1 addition & 0 deletions tests/test_leaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"multidict_type_leak.py",
"multidict_type_leak_items_values.py",
"multidict_pop.py",
"multidict_global_counter.py",
),
)
@pytest.mark.leaks
Expand Down
Loading