1212 _region = 0xffff
1313
1414 @contextlib .contextmanager
15- def _locked (fileno ):
16- while True :
17- try :
18- msvcrt .locking (fileno , msvcrt .LK_LOCK , _region )
19- except OSError as e :
20- # Locking violation. Returned when the _LK_LOCK or _LK_RLCK
21- # flag is specified and the file cannot be locked after 10
22- # attempts.
23- if e .errno != errno .EDEADLOCK :
24- raise
25- else :
26- break
15+ def _locked (fileno , blocked_cb ):
16+ try :
17+ msvcrt .locking (fileno , msvcrt .LK_NBLCK , _region )
18+ except IOError :
19+ blocked_cb ()
20+ while True :
21+ try :
22+ msvcrt .locking (fileno , msvcrt .LK_LOCK , _region )
23+ except IOError as e :
24+ # Locking violation. Returned when the _LK_LOCK or _LK_RLCK
25+ # flag is specified and the file cannot be locked after 10
26+ # attempts.
27+ if e .errno != errno .EDEADLOCK :
28+ raise
29+ else :
30+ break
2731
2832 try :
2933 yield
@@ -38,16 +42,20 @@ def _locked(fileno):
3842 import fcntl
3943
4044 @contextlib .contextmanager
41- def _locked (fileno ):
42- fcntl .flock (fileno , fcntl .LOCK_EX )
45+ def _locked (fileno , blocked_cb ):
46+ try :
47+ fcntl .flock (fileno , fcntl .LOCK_EX | fcntl .LOCK_NB )
48+ except IOError :
49+ blocked_cb ()
50+ fcntl .flock (fileno , fcntl .LOCK_EX )
4351 try :
4452 yield
4553 finally :
4654 fcntl .flock (fileno , fcntl .LOCK_UN )
4755
4856
4957@contextlib .contextmanager
50- def lock (path ):
58+ def lock (path , blocked_cb ):
5159 with open (path , 'a+' ) as f :
52- with _locked (f .fileno ()):
60+ with _locked (f .fileno (), blocked_cb ):
5361 yield
0 commit comments