@@ -319,7 +319,7 @@ static PyType_Spec lock_type_spec = {
319
319
typedef struct {
320
320
PyObject_HEAD
321
321
PyThread_type_lock rlock_lock ;
322
- unsigned long rlock_owner ;
322
+ uintptr_t rlock_owner ;
323
323
unsigned long rlock_count ;
324
324
PyObject * in_weakreflist ;
325
325
} rlockobject ;
@@ -331,7 +331,6 @@ rlock_traverse(rlockobject *self, visitproc visit, void *arg)
331
331
return 0 ;
332
332
}
333
333
334
-
335
334
static void
336
335
rlock_dealloc (rlockobject * self )
337
336
{
@@ -352,18 +351,24 @@ rlock_dealloc(rlockobject *self)
352
351
Py_DECREF (tp );
353
352
}
354
353
354
+ static int
355
+ rlock_is_owned (rlockobject * self )
356
+ {
357
+ uintptr_t tid = _Py_ThreadId ();
358
+ uintptr_t owner_tid = _Py_atomic_load_uintptr_relaxed (& self -> rlock_owner );
359
+ return owner_tid == tid && self -> rlock_count > 0 ;
360
+ }
361
+
355
362
static PyObject *
356
363
rlock_acquire (rlockobject * self , PyObject * args , PyObject * kwds )
357
364
{
358
365
_PyTime_t timeout ;
359
- unsigned long tid ;
360
366
PyLockStatus r = PY_LOCK_ACQUIRED ;
361
367
362
368
if (lock_acquire_parse_args (args , kwds , & timeout ) < 0 )
363
369
return NULL ;
364
370
365
- tid = PyThread_get_thread_ident ();
366
- if (self -> rlock_count > 0 && tid == self -> rlock_owner ) {
371
+ if (rlock_is_owned (self )) {
367
372
unsigned long count = self -> rlock_count + 1 ;
368
373
if (count <= self -> rlock_count ) {
369
374
PyErr_SetString (PyExc_OverflowError ,
@@ -376,7 +381,7 @@ rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
376
381
r = acquire_timed (self -> rlock_lock , timeout );
377
382
if (r == PY_LOCK_ACQUIRED ) {
378
383
assert (self -> rlock_count == 0 );
379
- self -> rlock_owner = tid ;
384
+ _Py_atomic_store_uintptr_relaxed ( & self -> rlock_owner , _Py_ThreadId ()) ;
380
385
self -> rlock_count = 1 ;
381
386
}
382
387
else if (r == PY_LOCK_INTR ) {
@@ -405,15 +410,13 @@ the lock is taken and its internal counter initialized to 1.");
405
410
static PyObject *
406
411
rlock_release (rlockobject * self , PyObject * Py_UNUSED (ignored ))
407
412
{
408
- unsigned long tid = PyThread_get_thread_ident ();
409
-
410
- if (self -> rlock_count == 0 || self -> rlock_owner != tid ) {
413
+ if (!rlock_is_owned (self )) {
411
414
PyErr_SetString (PyExc_RuntimeError ,
412
- "cannot release un-acquired lock " );
415
+ "cannot release un-acquired lock1 " );
413
416
return NULL ;
414
417
}
415
418
if (-- self -> rlock_count == 0 ) {
416
- self -> rlock_owner = 0 ;
419
+ _Py_atomic_store_uintptr_relaxed ( & self -> rlock_owner , 0 ) ;
417
420
PyThread_release_lock (self -> rlock_lock );
418
421
}
419
422
Py_RETURN_NONE ;
@@ -434,11 +437,11 @@ to be available for other threads.");
434
437
static PyObject *
435
438
rlock_acquire_restore (rlockobject * self , PyObject * args )
436
439
{
437
- unsigned long owner ;
440
+ unsigned long long owner ;
438
441
unsigned long count ;
439
442
int r = 1 ;
440
443
441
- if (!PyArg_ParseTuple (args , "(kk ):_acquire_restore" , & count , & owner ))
444
+ if (!PyArg_ParseTuple (args , "(kK ):_acquire_restore" , & count , & owner ))
442
445
return NULL ;
443
446
444
447
if (!PyThread_acquire_lock (self -> rlock_lock , 0 )) {
@@ -451,7 +454,7 @@ rlock_acquire_restore(rlockobject *self, PyObject *args)
451
454
return NULL ;
452
455
}
453
456
assert (self -> rlock_count == 0 );
454
- self -> rlock_owner = owner ;
457
+ _Py_atomic_store_uintptr_relaxed ( & self -> rlock_owner , ( uintptr_t ) owner ) ;
455
458
self -> rlock_count = count ;
456
459
Py_RETURN_NONE ;
457
460
}
@@ -464,7 +467,7 @@ For internal use by `threading.Condition`.");
464
467
static PyObject *
465
468
rlock_release_save (rlockobject * self , PyObject * Py_UNUSED (ignored ))
466
469
{
467
- unsigned long owner ;
470
+ uintptr_t owner ;
468
471
unsigned long count ;
469
472
470
473
if (self -> rlock_count == 0 ) {
@@ -476,9 +479,9 @@ rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
476
479
owner = self -> rlock_owner ;
477
480
count = self -> rlock_count ;
478
481
self -> rlock_count = 0 ;
479
- self -> rlock_owner = 0 ;
482
+ _Py_atomic_store_uintptr_relaxed ( & self -> rlock_owner , 0 ) ;
480
483
PyThread_release_lock (self -> rlock_lock );
481
- return Py_BuildValue ("kk " , count , owner );
484
+ return Py_BuildValue ("kK " , count , ( unsigned long long ) owner );
482
485
}
483
486
484
487
PyDoc_STRVAR (rlock_release_save_doc ,
@@ -488,11 +491,9 @@ For internal use by `threading.Condition`.");
488
491
489
492
490
493
static PyObject *
491
- rlock_is_owned (rlockobject * self , PyObject * Py_UNUSED (ignored ))
494
+ rlock__is_owned (rlockobject * self , PyObject * Py_UNUSED (ignored ))
492
495
{
493
- unsigned long tid = PyThread_get_thread_ident ();
494
-
495
- if (self -> rlock_count > 0 && self -> rlock_owner == tid ) {
496
+ if (rlock_is_owned (self )) {
496
497
Py_RETURN_TRUE ;
497
498
}
498
499
Py_RETURN_FALSE ;
@@ -526,9 +527,11 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
526
527
static PyObject *
527
528
rlock_repr (rlockobject * self )
528
529
{
529
- return PyUnicode_FromFormat ("<%s %s object owner=%ld count=%lu at %p>" ,
530
+ uintptr_t owner = _Py_atomic_load_uintptr_relaxed (& self -> rlock_owner );
531
+
532
+ return PyUnicode_FromFormat ("<%s %s object owner=%p count=%llu at %p>" ,
530
533
self -> rlock_count ? "locked" : "unlocked" ,
531
- Py_TYPE (self )-> tp_name , self -> rlock_owner ,
534
+ Py_TYPE (self )-> tp_name , ( const void * ) owner ,
532
535
self -> rlock_count , self );
533
536
}
534
537
@@ -555,7 +558,7 @@ static PyMethodDef rlock_methods[] = {
555
558
METH_VARARGS | METH_KEYWORDS , rlock_acquire_doc },
556
559
{"release" , (PyCFunction )rlock_release ,
557
560
METH_NOARGS , rlock_release_doc },
558
- {"_is_owned" , (PyCFunction )rlock_is_owned ,
561
+ {"_is_owned" , (PyCFunction )rlock__is_owned ,
559
562
METH_NOARGS , rlock_is_owned_doc },
560
563
{"_acquire_restore" , (PyCFunction )rlock_acquire_restore ,
561
564
METH_VARARGS , rlock_acquire_restore_doc },
@@ -1272,7 +1275,7 @@ thread_run(void *boot_raw)
1272
1275
#endif
1273
1276
_PyThreadState_SetCurrent (tstate );
1274
1277
PyEval_AcquireThread (tstate );
1275
- tstate -> interp -> threads .count ++ ;
1278
+ _Py_atomic_add_ssize ( & tstate -> interp -> threads .count , 1 ) ;
1276
1279
1277
1280
PyObject * res = PyObject_Call (boot -> func , boot -> args , boot -> kwargs );
1278
1281
if (res == NULL ) {
@@ -1288,7 +1291,7 @@ thread_run(void *boot_raw)
1288
1291
}
1289
1292
1290
1293
thread_bootstate_free (boot );
1291
- tstate -> interp -> threads .count -- ;
1294
+ _Py_atomic_add_ssize ( & tstate -> interp -> threads .count , -1 ) ;
1292
1295
PyThreadState_Clear (tstate );
1293
1296
_PyThreadState_DeleteCurrent (tstate );
1294
1297
@@ -1531,7 +1534,7 @@ static PyObject *
1531
1534
thread__count (PyObject * self , PyObject * Py_UNUSED (ignored ))
1532
1535
{
1533
1536
PyInterpreterState * interp = _PyInterpreterState_GET ();
1534
- return PyLong_FromLong ( interp -> threads .count );
1537
+ return PyLong_FromSize_t ( _Py_atomic_load_ssize ( & interp -> threads .count ) );
1535
1538
}
1536
1539
1537
1540
PyDoc_STRVAR (_count_doc ,
0 commit comments