From 5cb213f30b3d2149dcf802968aadd02e9a50efef Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 10 Mar 2023 10:24:45 +0000
Subject: [PATCH] ENH: New lockdir utility function

---
 bip/utils/__init__.py | 58 +++++++++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/bip/utils/__init__.py b/bip/utils/__init__.py
index 4cbd17a..e97e100 100644
--- a/bip/utils/__init__.py
+++ b/bip/utils/__init__.py
@@ -1,13 +1,45 @@
-import shutil
-from fsl.wrappers.wrapperutils import cmdwrapper
-
-installed_sienax = shutil.which('bb_sienax')
-
-if installed_sienax:
-    @cmdwrapper
-    def bb_sienax(input, output=None, **kwargs):
-        return ['bb_sienax', input, output]
-else:
-    def bb_sienax(input, output=None, **kwargs):
-        from . import sienax
-        sienax.bb_sienax(input, output)
+#!/usr/bin/env python
+"""The bip.utils package contains a range of miscellaneous utilities. """
+
+
+import            contextlib
+import            logging
+import os.path as op
+import            os
+import            time
+
+
+log = logging.getLogger(__name__)
+
+
+@contextlib.contextmanager
+def lockdir(dirname, delay=5):
+    """Lock a directory for exclusive access.
+
+    Primitive mechanism by which concurrent access to a directory can be
+    prevented. Attempts to create a semaphore file in the directory, but waits
+    if that file already exists. Removes the file when finished.
+    """
+
+    lockfile = op.join(dirname, '.fsl_ci.lockdir')
+
+    while True:
+        try:
+            log.debug(f'Attempting to lock %s for exclusive access.', dirname)
+            fd = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+            break
+        except OSError as e:
+            if e.errno != errno.EEXIST:
+                raise e
+            log.debug('%s is already locked - trying again '
+                      'in %s seconds ...', dirname, delay)
+        time.sleep(10)
+
+    log.debug('Exclusive access acquired for %s ...', dirname)
+    try:
+        yield
+
+    finally:
+        log.debug('Relinquishing lock on %s', dirname)
+        os.close( fd)
+        os.unlink(lockfile)
-- 
GitLab