Skip to content

Commit 5f86b4e

Browse files
committed
Make use of folders which are concurrent safe
1 parent c3b671d commit 5f86b4e

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

mbed/mbed.py

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,61 +1343,76 @@ def set_cache(self, url):
13431343

13441344
def cache_lock(self, url):
13451345
cpath = self.url2cachedir(url)
1346-
if cpath:
1347-
lock_file = os.path.join(cpath, '.lock')
1346+
if not cpath:
1347+
return False
13481348

1349-
if not os.path.isdir(cpath):
1350-
os.makedirs(cpath)
1349+
if not os.path.isdir(cpath):
1350+
os.makedirs(cpath)
13511351

1352-
can_lock = False
1353-
# this loop is handling a lock file from another process if exists
1354-
for i in range(300):
1355-
if i:
1356-
time.sleep(1)
1352+
lock_dir = os.path.join(cpath, '.lock')
1353+
lock_file = os.path.join(lock_dir, 'pid')
13571354

1358-
try:
1359-
# lock file exists, but we need to check pid as well in case the process died
1360-
if os.path.isfile(lock_file):
1361-
with open(lock_file, 'r', 0) as f:
1362-
pid = int(f.read(8))
1363-
if pid != os.getpid() and self.pid_exists(pid):
1364-
info("Cache lock file exists and process %s is alive." % pid)
1365-
else:
1366-
info("Cache lock file exists, but %s is dead. Cleaning up" % pid)
1367-
os.remove(lock_file)
1368-
continue
1355+
# this loop is handling a lock file from another process if exists
1356+
for i in range(300):
1357+
if i:
1358+
time.sleep(1)
13691359

1360+
# lock file exists, but we need to check pid as well in case the process died
1361+
if os.path.exists(lock_dir):
1362+
if os.path.isfile(lock_file):
1363+
with open(lock_file, 'r', 0) as f:
1364+
pid = int(f.read(8))
1365+
if pid != os.getpid() and self.pid_exists(pid):
1366+
info("Cache lock file exists and process %s is alive." % pid)
1367+
else:
1368+
info("Cache lock file exists, but %s is dead. Cleaning up" % pid)
1369+
os.remove(lock_file)
1370+
os.rmdir(lock_dir)
1371+
else:
1372+
os.rmdir(lock_dir)
1373+
continue
1374+
else:
1375+
try:
1376+
os.mkdir(lock_dir)
13701377
with open(lock_file, 'wb', 0) as f:
13711378
info("Writing cache lock file %s for pid %s" % (lock_file, os.getpid()))
13721379
f.write(str(os.getpid()))
13731380
f.flush()
13741381
os.fsync(f)
1375-
break
1376-
except (IOError, OSError):
1377-
error("OS error occurred")
1378-
except Exception as e:
1379-
error("Weird error occurred")
1380-
1381-
else:
1382-
error("Exceeded 5 minutes limit while waiting for other process to finish caching")
1383-
return False
1382+
break
1383+
except (OSError, WindowsError) as e:
1384+
## Windows:
1385+
## <type 'exceptions.WindowsError'> 17 [Error 183] Cannot create a file when that file already exists: 'testing'
1386+
## or when concurrent: 13 WindowsError(5, 'Access is denied')
1387+
## Linux: <type 'exceptions.OSError'> 17 [Errno 17] File exists: 'testing'
1388+
## or when concurrent & virtualbox 71, OSError(71, 'Protocol error')
1389+
## or when full: 28, OSError(28, 'No space left on device')
1390+
if e.errno in (17,13,71,28):
1391+
continue
1392+
else:
1393+
raise e
1394+
else:
1395+
error("Exceeded 5 minutes limit while waiting for other process to finish caching")
1396+
return True
13841397

13851398
def cache_unlock(self, url):
13861399
cpath = self.url2cachedir(url)
1387-
if cpath:
1388-
lock_file = os.path.join(cpath, '.lock')
1400+
if not cpath:
1401+
return False
1402+
lock_dir = os.path.join(cpath, '.lock')
1403+
lock_file = os.path.join(lock_dir, 'pid')
1404+
if os.path.exists(lock_dir):
13891405
if os.path.isfile(lock_file):
13901406
try:
13911407
with open(lock_file, 'r', 0) as f:
13921408
pid = f.read(8)
1393-
if int(pid) == os.getpid():
1394-
os.remove(lock_file)
1395-
else:
1409+
if int(pid) != os.getpid():
13961410
error("Cache lock file exists with a different pid (\"%s\" vs \"%s\")" % (pid, os.getpid()))
1397-
except Exception:
1411+
except OSError:
13981412
error("Unable to unlock cache dir \"%s\"" % (cpath))
1399-
return True
1400-
return False
1413+
os.remove(lock_file)
1414+
os.rmdir(lock_dir)
1415+
return True
14011416

14021417
def pid_exists(self, pid):
14031418
try:

0 commit comments

Comments
 (0)