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