diff options
author | Hans Bolinder <[email protected]> | 2014-04-10 15:23:44 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2014-10-23 08:59:29 +0200 |
commit | 89c5bc9a243d7f0ba8e43b52b9addadccdb7d1ca (patch) | |
tree | 3faeb5fb24999a54b190bac9b844a89e93d9ac54 /lib/stdlib/src/dets.erl | |
parent | cd5628a99bff391377042f93e8d85da818235217 (diff) | |
download | otp-89c5bc9a243d7f0ba8e43b52b9addadccdb7d1ca.tar.gz otp-89c5bc9a243d7f0ba8e43b52b9addadccdb7d1ca.tar.bz2 otp-89c5bc9a243d7f0ba8e43b52b9addadccdb7d1ca.zip |
Fix rare race condition in Dets
The correction is due to the the evil testcase
dets_SUITE:simultaneous_open(). If the process repairing a Dets file
is killed (should normally never happen), and another process tries to
repair the file, a temporary file from the first process could live on
for a while, even after a successful call to file:delete(). This has
only been seen on W-nd-ows, where it is a known problem.
There are other ways to deal with the problem (rename the file; use
some other filename), but we continue using one certain filename in
order to be as backwards compatible as possible.
Diffstat (limited to 'lib/stdlib/src/dets.erl')
-rw-r--r-- | lib/stdlib/src/dets.erl | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl index 76e03bbfaa..a4bd45ea19 100644 --- a/lib/stdlib/src/dets.erl +++ b/lib/stdlib/src/dets.erl @@ -2839,17 +2839,22 @@ fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) -> tempfile(Fname) -> Tmp = lists:concat([Fname, ".TMP"]), - tempfile(Tmp, 10). - -tempfile(Tmp, 0) -> - Tmp; -tempfile(Tmp, N) -> case file:delete(Tmp) of - {error, eacces} -> % 'dets_process_died' happened anyway... (W-nd-ws) - timer:sleep(1000), - tempfile(Tmp, N-1); - _ -> - Tmp + {error, _Reason} -> % typically enoent + ok; + ok -> + assure_no_file(Tmp) + end, + Tmp. + +assure_no_file(File) -> + case file:read_file_info(File) of + {ok, _FileInfo} -> + %% Wait for some other process to close the file: + timer:sleep(100), + assure_no_file(File); + {error, _} -> + ok end. %% -> {ok, NewHead} | {try_again, integer()} | Error |