Skip to content

Commit

Permalink
fix: pass O_SHARE_DELETE when digesting files (ocaml#8262)
Browse files Browse the repository at this point in the history
Fixes ocaml#8268

This flag corresponds to what `Stdlib.open_in` does. When passed, the
files can be removed while they are still open. This condition can
happen when background digests are enabled. This is a no-op everywhere
else.

This allows enabling background digests on Windows.

Signed-off-by: Etienne Millon <me@emillon.org>
  • Loading branch information
emillon authored and Philip White committed Aug 10, 2023
1 parent 0ab223a commit c78ac88
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Unreleased
- Improve `dune describe external-lib-deps` by adding the internal dependencies
for more information. (#7478, @moyodiallo)

- Re-enable background file digests on Windows. The files are now open in a way
that prevents race condition around deletion. (#8262, fixes #8268, @emillon)

3.9.2 (2023-07-25)
------------------

Expand Down
5 changes: 1 addition & 4 deletions src/dune_config/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,7 @@ let background_digests =
let t =
{ name = "background_digests"
; of_string = Toggle.of_string
; value =
(match Platform.OS.value with
| Linux -> `Enabled
| _ -> `Disabled)
; value = background_default
}
in
register t;
Expand Down
6 changes: 5 additions & 1 deletion src/dune_digest/dune_digest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ end

module Direct_impl : Digest_impl = struct
let file file =
(* On Windows, if this function is invoked in a background thread,
if can happen that the file is not properly closed.
[O_SHARE_DELETE] ensures that the main thread can delete it even if it
is still open. See #8243. *)
let fd =
match Unix.openfile file [ Unix.O_RDONLY ] 0 with
match Unix.openfile file [ Unix.O_RDONLY; O_SHARE_DELETE ] 0 with
| fd -> fd
| exception Unix.Unix_error (Unix.EACCES, _, _) ->
raise (Sys_error (sprintf "%s: Permission denied" file))
Expand Down

0 comments on commit c78ac88

Please sign in to comment.