@@ -208,46 +208,73 @@ def _file_path(self):
208
208
class _FileLocker :
209
209
def __init__ (self , fd ):
210
210
self ._fd = fd
211
+ self ._lock_fd = None
212
+ self ._already_locked = False
211
213
212
214
def __enter__ (self ):
213
215
try :
214
- msvcrt .locking (self ._fd .fileno (), msvcrt .LK_LOCK | msvcrt .LK_NBLCK , 1 )
216
+ self ._lock_fd = open (self ._lock_file_path , 'w' )
217
+ msvcrt .locking (self ._lock_fd .fileno (), msvcrt .LK_LOCK | msvcrt .LK_NBLCK , 1 )
215
218
except OSError :
219
+ self ._already_locked = True
216
220
raise FileAlreadyLocked ('File {0} already locked' .format (self ._file_path ))
217
221
218
222
def __exit__ (self , exc_type , exc_val , exc_tb ):
219
- msvcrt .locking (self ._fd .fileno (), msvcrt .LK_UNLCK , 1 )
223
+ if self ._already_locked :
224
+ if self ._lock_fd :
225
+ self ._lock_fd .close ()
226
+ return
227
+
228
+ try :
229
+ msvcrt .locking (self ._lock_fd .fileno (), msvcrt .LK_UNLCK , 1 )
230
+ finally :
231
+ self ._lock_fd .close ()
232
+ os .remove (self ._lock_file_path )
233
+
220
234
221
235
@property
222
236
def _file_path (self ):
223
237
return self ._fd .name
224
238
239
+ @property
240
+ def _lock_file_path (self ):
241
+ """
242
+ Returns
243
+ -------
244
+ str
245
+ """
246
+ return self ._file_path + '.lock'
247
+
225
248
else :
226
249
class _FileLocker :
227
250
def __init__ (self , fd ):
228
251
self ._fd = fd
252
+ self ._already_locked = False
229
253
230
254
def __enter__ (self ):
231
255
try :
232
256
# Atomic file creation
233
257
open_flags = os .O_EXCL | os .O_RDWR | os .O_CREAT
234
- fd = os .open (self .lock_file_path , open_flags )
258
+ fd = os .open (self ._lock_file_path , open_flags )
235
259
os .close (fd )
236
- except IOError :
260
+ except OSError :
261
+ self ._already_locked = True
237
262
raise FileAlreadyLocked ('File {0} already locked' .format (self ._file_path ))
238
263
239
264
def __exit__ (self , exc_type , exc_val , exc_tb ):
265
+ if self ._already_locked :
266
+ return
240
267
try :
241
- os .remove (self .lock_file_path )
242
- except IOError :
268
+ os .remove (self ._lock_file_path )
269
+ except OSError :
243
270
pass
244
271
245
272
@property
246
273
def _file_path (self ):
247
274
return self ._fd .name
248
275
249
276
@property
250
- def lock_file_path (self ):
277
+ def _lock_file_path (self ):
251
278
"""
252
279
Returns
253
280
-------
@@ -770,6 +797,10 @@ def __shrink_cache(self):
770
797
os .chmod (shrink_file_path , 0o666 )
771
798
772
799
# rename file
800
+ if is_windows :
801
+ # windows must close first, or will raise permission error
802
+ # be careful to do something with the file after this
803
+ f .close ()
773
804
shutil .move (shrink_file_path , self ._cache_scope .persist_path )
774
805
775
806
# update last shrink time
0 commit comments