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
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 8 additions & 1 deletion 9 Include/internal/pycore_setobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

// Export for '_pickle' shared extension
// Export for '_abc' shared extension
PyAPI_FUNC(int) _PySet_NextEntry(
PyObject *set,
Py_ssize_t *pos,
PyObject **key,
Py_hash_t *hash);

// Export for '_pickle' shared extension
PyAPI_FUNC(int) _PySet_NextEntryRef(
PyObject *set,
Py_ssize_t *pos,
PyObject **key,
Py_hash_t *hash);

// Export for '_pickle' shared extension
PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);

Expand Down
2 changes: 1 addition & 1 deletion 2 Modules/_abc.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,

// Make a local copy of the registry to protect against concurrent
// modifications of _abc_registry.
PyObject *registry = PySet_New(registry_shared);
PyObject *registry = PyFrozenSet_New(registry_shared);
if (registry == NULL) {
return -1;
}
Expand Down
33 changes: 20 additions & 13 deletions 33 Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
#endif

#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytesWriter
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_object.h" // _PyNone_Type
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_runtime.h" // _Py_ID()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_sysmodule.h" // _PySys_GetAttr()
#include "pycore_bytesobject.h" // _PyBytesWriter
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_object.h" // _PyNone_Type
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_runtime.h" // _Py_ID()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_sysmodule.h" // _PySys_GetAttr()

#include <stdlib.h> // strtol()

Expand Down Expand Up @@ -3413,15 +3414,21 @@ save_set(PickleState *state, PicklerObject *self, PyObject *obj)
i = 0;
if (_Pickler_Write(self, &mark_op, 1) < 0)
return -1;
while (_PySet_NextEntry(obj, &ppos, &item, &hash)) {
Py_INCREF(item);
int err = save(state, self, item, 0);

int err = 0;
Py_BEGIN_CRITICAL_SECTION(obj);
while (_PySet_NextEntryRef(obj, &ppos, &item, &hash)) {
err = save(state, self, item, 0);
Py_CLEAR(item);
if (err < 0)
return -1;
break;
if (++i == BATCHSIZE)
break;
}
Py_END_CRITICAL_SECTION();
if (err < 0) {
return -1;
}
if (_Pickler_Write(self, &additems_op, 1) < 0)
return -1;
if (PySet_GET_SIZE(obj) != set_size) {
Expand Down
10 changes: 7 additions & 3 deletions 10 Modules/_testinternalcapi/set.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "parts.h"
#include "../_testcapi/util.h" // NULLABLE, RETURN_INT

#include "pycore_critical_section.h"
#include "pycore_setobject.h"


Expand All @@ -27,10 +28,13 @@ set_next_entry(PyObject *self, PyObject *args)
return NULL;
}
NULLABLE(set);

rc = _PySet_NextEntry(set, &pos, &item, &hash);
Py_BEGIN_CRITICAL_SECTION(set);
rc = _PySet_NextEntryRef(set, &pos, &item, &hash);
Py_END_CRITICAL_SECTION();
if (rc == 1) {
return Py_BuildValue("innO", rc, pos, hash, item);
PyObject *ret = Py_BuildValue("innO", rc, pos, hash, item);
Py_DECREF(item);
return ret;
}
assert(item == UNINITIALIZED_PTR);
assert(hash == (Py_hash_t)UNINITIALIZED_SIZE);
Expand Down
5 changes: 3 additions & 2 deletions 5 Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2979,8 +2979,9 @@ dict_set_fromkeys(PyInterpreterState *interp, PyDictObject *mp,
return NULL;
}

while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
if (insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value))) {
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(iterable);
while (_PySet_NextEntryRef(iterable, &pos, &key, &hash)) {
if (insertdict(interp, mp, key, hash, Py_NewRef(value))) {
Py_DECREF(mp);
return NULL;
}
Expand Down
3 changes: 1 addition & 2 deletions 3 Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,8 +1287,7 @@ list_extend_set(PyListObject *self, PySetObject *other)
Py_hash_t hash;
PyObject *key;
PyObject **dest = self->ob_item + m;
while (_PySet_NextEntry((PyObject *)other, &setpos, &key, &hash)) {
Py_INCREF(key);
while (_PySet_NextEntryRef((PyObject *)other, &setpos, &key, &hash)) {
FT_ATOMIC_STORE_PTR_RELEASE(*dest, key);
dest++;
}
Expand Down
18 changes: 17 additions & 1 deletion 18 Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2661,7 +2661,6 @@ PySet_Add(PyObject *anyset, PyObject *key)
return rv;
}

// TODO: Make thread-safe in free-threaded builds
int
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
Expand All @@ -2678,6 +2677,23 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash
return 1;
}

int
_PySet_NextEntryRef(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
setentry *entry;

if (!PyAnySet_Check(set)) {
PyErr_BadInternalCall();
return -1;
}
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(set);
if (set_next((PySetObject *)set, pos, &entry) == 0)
return 0;
*key = Py_NewRef(entry->key);
*hash = entry->hash;
return 1;
}

PyObject *
PySet_Pop(PyObject *set)
{
Expand Down
29 changes: 18 additions & 11 deletions 29 Python/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
and sharing. */

#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_code.h" // _PyCode_New()
#include "pycore_hashtable.h" // _Py_hashtable_t
#include "pycore_long.h" // _PyLong_DigitCount
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "marshal.h" // Py_MARSHAL_VERSION
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_code.h" // _PyCode_New()
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
#include "pycore_hashtable.h" // _Py_hashtable_t
#include "pycore_long.h" // _PyLong_DigitCount
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "marshal.h" // Py_MARSHAL_VERSION

#ifdef __APPLE__
# include "TargetConditionals.h"
Expand Down Expand Up @@ -531,23 +532,29 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
return;
}
Py_ssize_t i = 0;
while (_PySet_NextEntry(v, &pos, &value, &hash)) {
Py_BEGIN_CRITICAL_SECTION(v);
while (_PySet_NextEntryRef(v, &pos, &value, &hash)) {
PyObject *dump = _PyMarshal_WriteObjectToString(value,
p->version, p->allow_code);
if (dump == NULL) {
p->error = WFERR_UNMARSHALLABLE;
Py_DECREF(pairs);
return;
Py_DECREF(value);
break;
}
PyObject *pair = PyTuple_Pack(2, dump, value);
Py_DECREF(dump);
Py_DECREF(value);
if (pair == NULL) {
p->error = WFERR_NOMEMORY;
Py_DECREF(pairs);
return;
break;
}
PyList_SET_ITEM(pairs, i++, pair);
}
Py_END_CRITICAL_SECTION();
if (p->error == WFERR_UNMARSHALLABLE || p->error == WFERR_NOMEMORY) {
Py_DECREF(pairs);
return;
}
assert(i == n);
if (PyList_Sort(pairs)) {
p->error = WFERR_NOMEMORY;
Expand Down
1 change: 1 addition & 0 deletions 1 Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -2910,6 +2910,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
Py_ssize_t i = 0;
PyObject *item;
Py_hash_t hash;
// if stdlib_module_names is not NULL, it is always a frozenset.
while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) {
if (PyUnicode_Check(item)
&& PyUnicode_Compare(key, item) == 0)
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.