Skip to content

Commit d314fe0

Browse files
committed
add python implementation
1 parent 7e3653a commit d314fe0

File tree

2 files changed

+11
-109
lines changed

2 files changed

+11
-109
lines changed

Lib/threading.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from time import monotonic as _time
99
from _weakrefset import WeakSet
1010
from itertools import count as _count
11+
from collections.abc import Iterator
1112
try:
1213
from _collections import deque as _deque
1314
except ImportError:
@@ -42,7 +43,6 @@
4243
get_ident = _thread.get_ident
4344
_get_main_thread_ident = _thread._get_main_thread_ident
4445
_is_main_interpreter = _thread._is_main_interpreter
45-
iter_locked = _thread.iter_locked
4646
try:
4747
get_native_id = _thread.get_native_id
4848
_HAVE_THREAD_NATIVE_ID = True
@@ -1633,3 +1633,13 @@ def _after_fork():
16331633

16341634
if hasattr(_os, "register_at_fork"):
16351635
_os.register_at_fork(after_in_child=_after_fork)
1636+
1637+
class iter_locked(Iterator):
1638+
def __init__(self, it):
1639+
"""Convert an iterable into an iterator that performs iteration using locks """
1640+
self._it = iter(it)
1641+
self._lock = RLock()
1642+
1643+
def __next__(self):
1644+
with self._lock:
1645+
return next(self._it)

Modules/_threadmodule.c

Lines changed: 0 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ static struct PyModuleDef thread_module;
2727
// Module state
2828
typedef struct {
2929
PyTypeObject *excepthook_type;
30-
PyTypeObject *iter_locked_type;
3130
PyTypeObject *lock_type;
3231
PyTypeObject *rlock_type;
3332
PyTypeObject *local_type;
@@ -69,7 +68,6 @@ static PF_SET_THREAD_DESCRIPTION pSetThreadDescription = NULL;
6968

7069
/*[clinic input]
7170
module _thread
72-
class _thread.iter_locked "iter_locked_object *" "clinic_state()->iter_locked_type"
7371
class _thread.lock "lockobject *" "clinic_state()->lock_type"
7472
class _thread.RLock "rlockobject *" "clinic_state()->rlock_type"
7573
@@ -754,101 +752,6 @@ static PyType_Spec ThreadHandle_Type_spec = {
754752
ThreadHandle_Type_slots,
755753
};
756754

757-
/* iter_locked object **************************************************************/
758-
759-
typedef struct {
760-
PyObject_HEAD
761-
PyObject *it;
762-
_PyRecursiveMutex lock;
763-
} iter_locked_object;
764-
765-
#define iter_locked_object_CAST(op) ((iter_locked_object *)(op))
766-
767-
/*[clinic input]
768-
@classmethod
769-
_thread.iter_locked.__new__
770-
iterable: object
771-
/
772-
Make an iterator thread-safe.
773-
[clinic start generated code]*/
774-
775-
static PyObject *
776-
_thread_iter_locked_impl(PyTypeObject *type, PyObject *iterable)
777-
/*[clinic end generated code: output=4a8ad5a25f7c09ba input=ae6124177726e809]*/
778-
{
779-
/* Get iterator. */
780-
PyObject *it = PyObject_GetIter(iterable);
781-
if (it == NULL)
782-
return NULL;
783-
784-
iter_locked_object *il = (iter_locked_object *)type->tp_alloc(type, 0);
785-
if (il == NULL) {
786-
Py_DECREF(it);
787-
return NULL;
788-
}
789-
il->it = it;
790-
il->lock = (_PyRecursiveMutex){0};
791-
792-
return (PyObject *)il;
793-
}
794-
795-
static void
796-
iter_locked_dealloc(PyObject *op)
797-
{
798-
iter_locked_object *il = iter_locked_object_CAST(op);
799-
PyTypeObject *tp = Py_TYPE(il);
800-
PyObject_GC_UnTrack(il);
801-
Py_DECREF(il->it);
802-
tp->tp_free(il);
803-
Py_DECREF(tp);
804-
}
805-
806-
static int
807-
iter_locked_traverse(PyObject *op, visitproc visit, void *arg)
808-
{
809-
iter_locked_object *lz = iter_locked_object_CAST(op);
810-
Py_VISIT(Py_TYPE(lz));
811-
Py_VISIT(lz->it);
812-
return 0;
813-
}
814-
815-
static PyObject *
816-
iter_locked_next(PyObject *op)
817-
{
818-
iter_locked_object *lz = iter_locked_object_CAST(op);
819-
PyObject *result = NULL;
820-
821-
_PyRecursiveMutex_Lock(&(lz->lock));
822-
823-
int v = PyIter_NextItem(lz->it, &result);
824-
if (v == -1) {
825-
/* Note: StopIteration is already cleared by PyIter_Next() */
826-
/* If PyErr_Occurred() we will also return NULL*/
827-
}
828-
_PyRecursiveMutex_Unlock(&(lz->lock));
829-
830-
return result;
831-
}
832-
833-
static PyType_Slot iter_locked_slots[] = {
834-
{Py_tp_dealloc, iter_locked_dealloc},
835-
{Py_tp_getattro, PyObject_GenericGetAttr},
836-
{Py_tp_doc, (void *)_thread_iter_locked__doc__},
837-
{Py_tp_traverse, iter_locked_traverse},
838-
{Py_tp_iter, PyObject_SelfIter},
839-
{Py_tp_iternext, iter_locked_next},
840-
{Py_tp_new, _thread_iter_locked},
841-
{Py_tp_free, PyObject_GC_Del},
842-
{0, NULL},
843-
};
844-
845-
static PyType_Spec iter_locked_spec = {
846-
.name = "threading.iter_locked",
847-
.basicsize = sizeof(iter_locked_object),
848-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
849-
Py_TPFLAGS_IMMUTABLETYPE),
850-
.slots = iter_locked_slots,
851-
};
852755

853756
/* Lock objects */
854757

@@ -2759,15 +2662,6 @@ thread_module_exec(PyObject *module)
27592662
return -1;
27602663
}
27612664

2762-
// iter_locked
2763-
state->iter_locked_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &iter_locked_spec, NULL);
2764-
if (state->iter_locked_type == NULL) {
2765-
return -1;
2766-
}
2767-
if (PyModule_AddType(module, state->iter_locked_type) < 0) {
2768-
return -1;
2769-
}
2770-
27712665
// Lock
27722666
state->lock_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &lock_type_spec, NULL);
27732667
if (state->lock_type == NULL) {
@@ -2874,7 +2768,6 @@ thread_module_traverse(PyObject *module, visitproc visit, void *arg)
28742768
{
28752769
thread_module_state *state = get_thread_state(module);
28762770
Py_VISIT(state->excepthook_type);
2877-
Py_VISIT(state->iter_locked_type);
28782771
Py_VISIT(state->lock_type);
28792772
Py_VISIT(state->rlock_type);
28802773
Py_VISIT(state->local_type);
@@ -2888,7 +2781,6 @@ thread_module_clear(PyObject *module)
28882781
{
28892782
thread_module_state *state = get_thread_state(module);
28902783
Py_CLEAR(state->excepthook_type);
2891-
Py_CLEAR(state->iter_locked_type);
28922784
Py_CLEAR(state->lock_type);
28932785
Py_CLEAR(state->rlock_type);
28942786
Py_CLEAR(state->local_type);

0 commit comments

Comments
 (0)