Skip to content

Commit 15bddb5

Browse files
committed
Return lock holder info when taking global lock fails
Signed-off-by: Stephen Sherratt <[email protected]>
1 parent 6176bc6 commit 15bddb5

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

bin/build_cmd.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ let build =
205205
state of the lock could otherwise change between checking it and taking
206206
it. *)
207207
match Dune_util.Global_lock.lock ~timeout:None with
208-
| Error () ->
208+
| Error _lock_held_by ->
209209
(* This case is reached if dune detects that another instance of dune
210210
is already running. Rather than performing the build itself, the
211211
current instance of dune will instruct the already-running instance to

src/dune_util/global_lock.ml

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ end
6666

6767
let locked = ref false
6868

69+
module Lock_held_by = struct
70+
type t =
71+
| Pid_from_lockfile of string
72+
| Unknown
73+
74+
let read_lock_file () =
75+
match Io.read_file (Path.build lock_file) with
76+
| exception _ -> Unknown
77+
| pid -> Pid_from_lockfile pid
78+
;;
79+
80+
let message t =
81+
Pp.textf
82+
"A running dune%s instance has locked the build directory. If this is not the \
83+
case, please delete %S."
84+
(match t with
85+
| Unknown -> ""
86+
| Pid_from_lockfile pid -> sprintf " (pid: %s)" pid)
87+
(Path.Build.to_string_maybe_quoted lock_file)
88+
;;
89+
end
90+
6991
let lock ~timeout =
7092
match Config.(get global_lock) with
7193
| `Disabled -> Ok ()
@@ -90,22 +112,15 @@ let lock ~timeout =
90112
| `Success ->
91113
locked := true;
92114
Ok ()
93-
| `Failure -> Error ())
115+
| `Failure ->
116+
let lock_held_by = Lock_held_by.read_lock_file () in
117+
Error lock_held_by)
94118
;;
95119

96120
let lock_exn ~timeout =
97121
match lock ~timeout with
98122
| Ok () -> ()
99-
| Error () ->
100-
User_error.raise
101-
[ Pp.textf
102-
"A running dune%s instance has locked the build directory. If this is not the \
103-
case, please delete %s"
104-
(match Io.read_file (Path.build lock_file) with
105-
| exception _ -> ""
106-
| pid -> sprintf " (pid: %s)" pid)
107-
(Path.Build.to_string_maybe_quoted lock_file)
108-
]
123+
| Error lock_held_by -> User_error.raise [ Lock_held_by.message lock_held_by ]
109124
;;
110125

111126
let unlock () =

src/dune_util/global_lock.mli

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22
33
Before starting rpc, writing to the build dir, this lock should be locked. *)
44

5-
(** attempt to acquire a lock. once a lock is locked, subsequent locks always
5+
module Lock_held_by : sig
6+
type t
7+
8+
val message : t -> 'a Pp.t
9+
end
10+
11+
(** Attempt to acquire a lock. once a lock is locked, subsequent locks always
612
succeed. Returns [Ok ()] if the lock is acquired within [timeout] seconds,
713
and [Error ()] otherwise. *)
8-
val lock : timeout:float option -> (unit, unit) result
14+
val lock : timeout:float option -> (unit, Lock_held_by.t) result
915

1016
val lock_exn : timeout:float option -> unit
1117

0 commit comments

Comments
 (0)