Skip to content

Commit 60e8d53

Browse files
committed
WIP
1 parent 4170a35 commit 60e8d53

File tree

6 files changed

+45
-44
lines changed

6 files changed

+45
-44
lines changed

Modules/_pickle.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
#endif
1010

1111
#include "Python.h"
12-
#include "pycore_bytesobject.h" // _PyBytesWriter
13-
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
14-
#include "pycore_long.h" // _PyLong_AsByteArray()
15-
#include "pycore_moduleobject.h" // _PyModule_GetState()
16-
#include "pycore_object.h" // _PyNone_Type
17-
#include "pycore_pystate.h" // _PyThreadState_GET()
18-
#include "pycore_runtime.h" // _Py_ID()
19-
#include "pycore_setobject.h" // _PySet_NextEntry()
20-
#include "pycore_sysmodule.h" // _PySys_GetAttr()
12+
#include "pycore_bytesobject.h" // _PyBytesWriter
13+
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
14+
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
15+
#include "pycore_long.h" // _PyLong_AsByteArray()
16+
#include "pycore_moduleobject.h" // _PyModule_GetState()
17+
#include "pycore_object.h" // _PyNone_Type
18+
#include "pycore_pystate.h" // _PyThreadState_GET()
19+
#include "pycore_runtime.h" // _Py_ID()
20+
#include "pycore_setobject.h" // _PySet_NextEntry()
21+
#include "pycore_sysmodule.h" // _PySys_GetAttr()
2122

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

@@ -3413,15 +3414,22 @@ save_set(PickleState *state, PicklerObject *self, PyObject *obj)
34133414
i = 0;
34143415
if (_Pickler_Write(self, &mark_op, 1) < 0)
34153416
return -1;
3417+
3418+
int err;
3419+
Py_BEGIN_CRITICAL_SECTION(obj);
34163420
while (_PySet_NextEntry(obj, &ppos, &item, &hash)) {
34173421
Py_INCREF(item);
34183422
int err = save(state, self, item, 0);
34193423
Py_CLEAR(item);
34203424
if (err < 0)
3421-
return -1;
3425+
break;
34223426
if (++i == BATCHSIZE)
34233427
break;
34243428
}
3429+
Py_END_CRITICAL_SECTION();
3430+
if (err < 0) {
3431+
return -1;
3432+
}
34253433
if (_Pickler_Write(self, &additems_op, 1) < 0)
34263434
return -1;
34273435
if (PySet_GET_SIZE(obj) != set_size) {

Modules/_testinternalcapi/set.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "parts.h"
22
#include "../_testcapi/util.h" // NULLABLE, RETURN_INT
33

4+
#include "pycore_critical_section.h"
45
#include "pycore_setobject.h"
56

67

@@ -27,8 +28,9 @@ set_next_entry(PyObject *self, PyObject *args)
2728
return NULL;
2829
}
2930
NULLABLE(set);
30-
31+
Py_BEGIN_CRITICAL_SECTION(set);
3132
rc = _PySet_NextEntry(set, &pos, &item, &hash);
33+
Py_END_CRITICAL_SECTION();
3234
if (rc == 1) {
3335
return Py_BuildValue("innO", rc, pos, hash, item);
3436
}

Objects/dictobject.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,18 +2979,12 @@ dict_set_fromkeys(PyInterpreterState *interp, PyDictObject *mp,
29792979
return NULL;
29802980
}
29812981

2982-
int (*next_entry_ptr)(PyObject *, Py_ssize_t *, PyObject **, Py_hash_t *);
2983-
if (PyFrozenSet_CheckExact(iterable)) {
2984-
next_entry_ptr = &_PyFrozenSet_NextEntry;
2985-
}
2986-
else {
2987-
next_entry_ptr = &_PySet_NextEntry;
2988-
}
2989-
2990-
while ((*next_entry_ptr)(iterable, &pos, &key, &hash)) {
2982+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(iterable);
2983+
while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
29912984
if (insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value))) {
29922985
Py_DECREF(mp);
2993-
return NULL;
2986+
mp = NULL;
2987+
break;
29942988
}
29952989
}
29962990
return mp;

Objects/listobject.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,23 +1282,18 @@ list_extend_set(PyListObject *self, PySetObject *other)
12821282
if (list_resize(self, m + n) < 0) {
12831283
return -1;
12841284
}
1285-
int (*next_entry_ptr)(PyObject *, Py_ssize_t *, PyObject **, Py_hash_t *);
1286-
if (PyFrozenSet_CheckExact(other)) {
1287-
next_entry_ptr = &_PyFrozenSet_NextEntry;
1288-
}
1289-
else {
1290-
next_entry_ptr = &_PySet_NextEntry;
1291-
}
12921285
/* populate the end of self with iterable's items */
12931286
Py_ssize_t setpos = 0;
12941287
Py_hash_t hash;
12951288
PyObject *key;
12961289
PyObject **dest = self->ob_item + m;
1297-
while ((*next_entry_ptr)((PyObject *)other, &setpos, &key, &hash)) {
1290+
Py_BEGIN_CRITICAL_SECTION(other);
1291+
while (_PySet_NextEntry((PyObject *)other, &setpos, &key, &hash)) {
12981292
Py_INCREF(key);
12991293
FT_ATOMIC_STORE_PTR_RELEASE(*dest, key);
13001294
dest++;
13011295
}
1296+
Py_END_CRITICAL_SECTION();
13021297
Py_SET_SIZE(self, m + n);
13031298
return 0;
13041299
}

Objects/setobject.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,11 +2681,8 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash
26812681
PyErr_BadInternalCall();
26822682
return -1;
26832683
}
2684-
int ret;
2685-
Py_BEGIN_CRITICAL_SECTION(set);
2686-
ret = _PySet_NextEntry_lock_held(set, pos, key, hash);
2687-
Py_END_CRITICAL_SECTION();
2688-
return ret;
2684+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(set);
2685+
return _PySet_NextEntry_lock_held(set, pos, key, hash);
26892686
}
26902687

26912688
int

Python/marshal.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
and sharing. */
88

99
#include "Python.h"
10-
#include "pycore_call.h" // _PyObject_CallNoArgs()
11-
#include "pycore_code.h" // _PyCode_New()
12-
#include "pycore_hashtable.h" // _Py_hashtable_t
13-
#include "pycore_long.h" // _PyLong_DigitCount
14-
#include "pycore_setobject.h" // _PySet_NextEntry()
15-
#include "marshal.h" // Py_MARSHAL_VERSION
10+
#include "pycore_call.h" // _PyObject_CallNoArgs()
11+
#include "pycore_code.h" // _PyCode_New()
12+
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
13+
#include "pycore_hashtable.h" // _Py_hashtable_t
14+
#include "pycore_long.h" // _PyLong_DigitCount
15+
#include "pycore_setobject.h" // _PySet_NextEntry()
16+
#include "marshal.h" // Py_MARSHAL_VERSION
1617

1718
#ifdef __APPLE__
1819
# include "TargetConditionals.h"
@@ -531,23 +532,27 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
531532
return;
532533
}
533534
Py_ssize_t i = 0;
535+
Py_BEGIN_CRITICAL_SECTION(v);
534536
while (_PySet_NextEntry(v, &pos, &value, &hash)) {
535537
PyObject *dump = _PyMarshal_WriteObjectToString(value,
536538
p->version, p->allow_code);
537539
if (dump == NULL) {
538540
p->error = WFERR_UNMARSHALLABLE;
539-
Py_DECREF(pairs);
540-
return;
541+
break;
541542
}
542543
PyObject *pair = PyTuple_Pack(2, dump, value);
543544
Py_DECREF(dump);
544545
if (pair == NULL) {
545546
p->error = WFERR_NOMEMORY;
546-
Py_DECREF(pairs);
547-
return;
547+
break;
548548
}
549549
PyList_SET_ITEM(pairs, i++, pair);
550550
}
551+
Py_END_CRITICAL_SECTION();
552+
if (p->error == WFERR_UNMARSHALLABLE || p->error == WFERR_NOMEMORY) {
553+
Py_DECREF(pairs);
554+
return;
555+
}
551556
assert(i == n);
552557
if (PyList_Sort(pairs)) {
553558
p->error = WFERR_NOMEMORY;

0 commit comments

Comments
 (0)