sclass FileBasedLock implements AutoCloseable { File lockFile; double timeout = 60.0; // in seconds. refresh happens twice as often bool haveLock; java.util.Timer touchTimer; *() {} *(File *lockFile) {} *(File *lockFile, double *timeout) {} // returns true iff lock was acquired (or kept) synchronized bool tryToLock() { if (haveLock) true; double age = fileAgeInSeconds(lockFile); if (age >= timeout) { print("Deleting old lock file: " + lockFile + " (age: " + iround(age) + " seconds)"); deleteFile(lockFile); } try { java.nio.file.Files.createFile(toPath(lockFile)); set haveLock; startTouchTimer(); true; } catch e { printExceptionShort(e); false; } } synchronized void startTouchTimer { if (touchTimer != null) ret; touchTimer = doEvery(timeout/2, r doTouch); } synchronized void doTouch { if (haveLock) touchFile(lockFile); } public synchronized void close() pcall { dispose touchTimer; if (haveLock) { haveLock = false; deleteFile(lockFile); } } synchronized void _simulateCrash { dispose touchTimer; } }