@@ -422,8 +422,7 @@ class Lock:
422
422
423
423
def __init__ (self ) -> None :
424
424
self ._waiters : Optional [Deque [asyncio .Future [Any ]]] = None
425
- self ._locked = False
426
- self ._lock = threading .RLock ()
425
+ self ._locked = [False ] # make locked atomic according to GIL
427
426
self ._locker : Optional [asyncio .Task [Any ]] = None
428
427
429
428
async def __aenter__ (self ) -> None :
@@ -443,20 +442,23 @@ def __repr__(self) -> str:
443
442
444
443
@property
445
444
def locked (self ) -> bool :
446
- return self ._locked
445
+ return self ._locked [0 ]
446
+
447
+ def _set_locked (self , value : bool ) -> None :
448
+ self ._locked [0 ] = value
449
+ self ._locker = asyncio .current_task () if value else None
447
450
448
451
async def acquire (self ) -> bool :
449
- with self ._lock :
450
- if not self ._locked and (self ._waiters is None or all (w .cancelled () for w in self ._waiters )):
451
- self ._locked = True
452
- self ._locker = asyncio .current_task ()
453
- return True
452
+ if not self .locked and (self ._waiters is None or all (w .cancelled () for w in self ._waiters )):
453
+ self ._set_locked (True )
454
+
455
+ return True
454
456
455
- if self ._waiters is None :
456
- self ._waiters = deque ()
457
+ if self ._waiters is None :
458
+ self ._waiters = deque ()
457
459
458
- fut = create_sub_future ()
459
- self ._waiters .append (fut )
460
+ fut = create_sub_future ()
461
+ self ._waiters .append (fut )
460
462
461
463
try :
462
464
try :
@@ -471,39 +473,31 @@ def aaa(fut: asyncio.Future[Any]) -> None:
471
473
finally :
472
474
h .cancel ()
473
475
finally :
474
- with self ._lock :
475
- self ._waiters .remove (fut )
476
+ self ._waiters .remove (fut )
476
477
except asyncio .CancelledError :
477
- if not self ._locked :
478
+ if not self .locked :
478
479
self ._wake_up_first ()
479
480
raise
480
481
481
- with self ._lock :
482
- self ._locked = True
483
- self ._locker = asyncio .current_task ()
482
+ self ._set_locked (True )
484
483
485
484
return True
486
485
487
486
def release (self ) -> None :
488
- with self ._lock :
489
- wake_up = False
490
- if self ._locked :
491
- self ._locked = False
492
- self ._locker = None
493
- wake_up = True
494
-
495
- if wake_up :
487
+ if self .locked :
488
+ self ._set_locked (False )
496
489
self ._wake_up_first ()
490
+ else :
491
+ raise RuntimeError ("Lock is not acquired." )
497
492
498
493
def _wake_up_first (self ) -> None :
499
494
if not self ._waiters :
500
495
return
501
496
502
- with self ._lock :
503
- try :
504
- fut = next (iter (self ._waiters ))
505
- except StopIteration :
506
- return
497
+ try :
498
+ fut = next (iter (self ._waiters ))
499
+ except StopIteration :
500
+ return
507
501
508
502
if fut .get_loop ().is_running () and not fut .get_loop ().is_closed ():
509
503
if fut .get_loop () == asyncio .get_running_loop ():
@@ -532,8 +526,7 @@ def set_result(w: asyncio.Future[Any], ev: threading.Event) -> None:
532
526
time .sleep (0.001 )
533
527
else :
534
528
warnings .warn (f"Future { repr (fut )} loop is closed" )
535
- with self ._lock :
536
- self ._waiters .remove (fut )
529
+ self ._waiters .remove (fut )
537
530
self ._wake_up_first ()
538
531
539
532
0 commit comments