aboutsummaryrefslogtreecommitdiff
path: root/guix/build/syscalls.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2019-06-03 16:23:01 +0200
committerLudovic Courtès <ludo@gnu.org>2019-06-05 23:10:36 +0200
commitb7178c22bf642919345095aff9e34e02c00d5762 (patch)
tree3ae97ad3afecd9499104b1ed0b36e3a8b00a6b91 /guix/build/syscalls.scm
parentc11ac62de92c54d1422b4de6d2b50c3b2c1bbc87 (diff)
downloadguix-b7178c22bf642919345095aff9e34e02c00d5762.tar
guix-b7178c22bf642919345095aff9e34e02c00d5762.tar.gz
syscalls: Add 'with-file-lock' macro.
* guix/scripts/offload.scm (lock-file, unlock-file, with-file-lock): Move to... * guix/build/syscalls.scm: ... here.
Diffstat (limited to 'guix/build/syscalls.scm')
-rw-r--r--guix/build/syscalls.scm27
1 files changed, 27 insertions, 0 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 3abe65bc4f..04fbebb8a2 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -81,7 +81,11 @@
fdatasync
pivot-root
scandir*
+
fcntl-flock
+ lock-file
+ unlock-file
+ with-file-lock
set-thread-name
thread-name
@@ -1067,6 +1071,29 @@ exception if it's already taken."
;; Presumably we got EAGAIN or so.
(throw 'flock-error err))))))
+(define (lock-file file)
+ "Wait and acquire an exclusive lock on FILE. Return an open port."
+ (let ((port (open-file file "w0")))
+ (fcntl-flock port 'write-lock)
+ port))
+
+(define (unlock-file port)
+ "Unlock PORT, a port returned by 'lock-file'."
+ (fcntl-flock port 'unlock)
+ (close-port port)
+ #t)
+
+(define-syntax-rule (with-file-lock file exp ...)
+ "Wait to acquire a lock on FILE and evaluate EXP in that context."
+ (let ((port (lock-file file)))
+ (dynamic-wind
+ (lambda ()
+ #t)
+ (lambda ()
+ exp ...)
+ (lambda ()
+ (unlock-file port)))))
+
;;;
;;; Miscellaneous, aka. 'prctl'.