19
19
# include <signal.h> // SIGINT
20
20
#endif
21
21
22
- #include "clinic/_threadmodule.c.h"
23
-
24
22
// ThreadError is just an alias to PyExc_RuntimeError
25
23
#define ThreadError PyExc_RuntimeError
26
24
@@ -31,6 +29,7 @@ static struct PyModuleDef thread_module;
31
29
typedef struct {
32
30
PyTypeObject * excepthook_type ;
33
31
PyTypeObject * lock_type ;
32
+ PyTypeObject * rlock_type ;
34
33
PyTypeObject * local_type ;
35
34
PyTypeObject * local_dummy_type ;
36
35
PyTypeObject * thread_handle_type ;
@@ -48,6 +47,17 @@ get_thread_state(PyObject *module)
48
47
return (thread_module_state * )state ;
49
48
}
50
49
50
+ static inline thread_module_state *
51
+ get_thread_state_by_cls (PyTypeObject * cls )
52
+ {
53
+ // Use PyType_GetModuleByDef() to handle (R)Lock subclasses.
54
+ PyObject * module = PyType_GetModuleByDef (cls , & thread_module );
55
+ if (module == NULL ) {
56
+ return NULL ;
57
+ }
58
+ return get_thread_state (module );
59
+ }
60
+
51
61
52
62
#ifdef MS_WINDOWS
53
63
typedef HRESULT (WINAPI * PF_GET_THREAD_DESCRIPTION )(HANDLE , PCWSTR * );
@@ -59,9 +69,14 @@ static PF_SET_THREAD_DESCRIPTION pSetThreadDescription = NULL;
59
69
60
70
/*[clinic input]
61
71
module _thread
72
+ class _thread.lock "lockobject *" "clinic_state()->lock_type"
73
+ class _thread.RLock "rlockobject *" "clinic_state()->rlock_type"
62
74
[clinic start generated code]*/
63
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=be8dbe5cc4b16df7 ]*/
75
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c5a0f8c492a0c263 ]*/
64
76
77
+ #define clinic_state () get_thread_state_by_cls(type)
78
+ #include "clinic/_threadmodule.c.h"
79
+ #undef clinic_state
65
80
66
81
// _ThreadHandle type
67
82
@@ -916,25 +931,21 @@ lock__at_fork_reinit(PyObject *op, PyObject *Py_UNUSED(dummy))
916
931
}
917
932
#endif /* HAVE_FORK */
918
933
919
- static lockobject * newlockobject (PyObject * module );
934
+ /*[clinic input]
935
+ @classmethod
936
+ _thread.lock.__new__ as lock_new
937
+ [clinic start generated code]*/
920
938
921
939
static PyObject *
922
- lock_new (PyTypeObject * type , PyObject * args , PyObject * kwargs )
940
+ lock_new_impl (PyTypeObject * type )
941
+ /*[clinic end generated code: output=eab660d5a4c05c8a input=260208a4e277d250]*/
923
942
{
924
- // convert to AC?
925
- if (!_PyArg_NoKeywords ("lock" , kwargs )) {
926
- goto error ;
927
- }
928
- if (!_PyArg_CheckPositional ("lock" , PyTuple_GET_SIZE (args ), 0 , 0 )) {
929
- goto error ;
943
+ lockobject * self = (lockobject * )type -> tp_alloc (type , 0 );
944
+ if (self == NULL ) {
945
+ return NULL ;
930
946
}
931
-
932
- PyObject * module = PyType_GetModuleByDef (type , & thread_module );
933
- assert (module != NULL );
934
- return (PyObject * )newlockobject (module );
935
-
936
- error :
937
- return NULL ;
947
+ self -> lock = (PyMutex ){0 };
948
+ return (PyObject * )self ;
938
949
}
939
950
940
951
@@ -1186,8 +1197,14 @@ PyDoc_STRVAR(rlock_is_owned_doc,
1186
1197
\n\
1187
1198
For internal use by `threading.Condition`." );
1188
1199
1200
+ /*[clinic input]
1201
+ @classmethod
1202
+ _thread.RLock.__new__ as rlock_new
1203
+ [clinic start generated code]*/
1204
+
1189
1205
static PyObject *
1190
- rlock_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
1206
+ rlock_new_impl (PyTypeObject * type )
1207
+ /*[clinic end generated code: output=bb4fb1edf6818df5 input=013591361bf1ac6e]*/
1191
1208
{
1192
1209
rlockobject * self = (rlockobject * ) type -> tp_alloc (type , 0 );
1193
1210
if (self == NULL ) {
@@ -1267,20 +1284,6 @@ static PyType_Spec rlock_type_spec = {
1267
1284
.slots = rlock_type_slots ,
1268
1285
};
1269
1286
1270
- static lockobject *
1271
- newlockobject (PyObject * module )
1272
- {
1273
- thread_module_state * state = get_thread_state (module );
1274
-
1275
- PyTypeObject * type = state -> lock_type ;
1276
- lockobject * self = (lockobject * )type -> tp_alloc (type , 0 );
1277
- if (self == NULL ) {
1278
- return NULL ;
1279
- }
1280
- self -> lock = (PyMutex ){0 };
1281
- return self ;
1282
- }
1283
-
1284
1287
/* Thread-local objects */
1285
1288
1286
1289
/* Quick overview:
@@ -2035,7 +2038,8 @@ Note: the default signal handler for SIGINT raises ``KeyboardInterrupt``."
2035
2038
static PyObject *
2036
2039
thread_PyThread_allocate_lock (PyObject * module , PyObject * Py_UNUSED (ignored ))
2037
2040
{
2038
- return (PyObject * ) newlockobject (module );
2041
+ thread_module_state * state = get_thread_state (module );
2042
+ return lock_new_impl (state -> lock_type );
2039
2043
}
2040
2044
2041
2045
PyDoc_STRVAR (allocate_lock_doc ,
@@ -2645,15 +2649,13 @@ thread_module_exec(PyObject *module)
2645
2649
}
2646
2650
2647
2651
// RLock
2648
- PyTypeObject * rlock_type = (PyTypeObject * )PyType_FromSpec ( & rlock_type_spec );
2649
- if (rlock_type == NULL ) {
2652
+ state -> rlock_type = (PyTypeObject * )PyType_FromModuleAndSpec ( module , & rlock_type_spec , NULL );
2653
+ if (state -> rlock_type == NULL ) {
2650
2654
return -1 ;
2651
2655
}
2652
- if (PyModule_AddType (module , rlock_type ) < 0 ) {
2653
- Py_DECREF (rlock_type );
2656
+ if (PyModule_AddType (module , state -> rlock_type ) < 0 ) {
2654
2657
return -1 ;
2655
2658
}
2656
- Py_DECREF (rlock_type );
2657
2659
2658
2660
// Local dummy
2659
2661
state -> local_dummy_type = (PyTypeObject * )PyType_FromSpec (& local_dummy_type_spec );
@@ -2740,6 +2742,7 @@ thread_module_traverse(PyObject *module, visitproc visit, void *arg)
2740
2742
thread_module_state * state = get_thread_state (module );
2741
2743
Py_VISIT (state -> excepthook_type );
2742
2744
Py_VISIT (state -> lock_type );
2745
+ Py_VISIT (state -> rlock_type );
2743
2746
Py_VISIT (state -> local_type );
2744
2747
Py_VISIT (state -> local_dummy_type );
2745
2748
Py_VISIT (state -> thread_handle_type );
@@ -2752,6 +2755,7 @@ thread_module_clear(PyObject *module)
2752
2755
thread_module_state * state = get_thread_state (module );
2753
2756
Py_CLEAR (state -> excepthook_type );
2754
2757
Py_CLEAR (state -> lock_type );
2758
+ Py_CLEAR (state -> rlock_type );
2755
2759
Py_CLEAR (state -> local_type );
2756
2760
Py_CLEAR (state -> local_dummy_type );
2757
2761
Py_CLEAR (state -> thread_handle_type );
0 commit comments