Skip to content

Commit

Permalink
cover: Fix a race condition in how the server is started as part of a…
Browse files Browse the repository at this point in the history
… call

Before sending a message to the cover server, the `call` function checks
if the server is running, starting it if it does not.

However, there is no locking/atomicity between the check and the start.
If there is a concurrent call, the server might be started in parallel
by another process and the `start()` call would return `{error,
{already_started, _}}`. This causes the function to fail with a
`badmatch` exception.

The code now accepts that the server is running after seeing the server
as stopped and retrying the call.

V2: Fix coding style by applying a suggested patch from Björn
    Gustavsson.
V3: Fix incorrect matching of `start()` return value: the correct
    pattern in `{error, {already_started, _}}`, not `{already_started, _}`.
    Found by Dialyzer, reported by Björn Gustavsson.

Co-authored-by: Björn Gustavsson <[email protected]>
  • Loading branch information
dumbbell and bjorng committed Feb 28, 2025
1 parent 647d2f0 commit 05e49fe
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/tools/src/cover.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,10 @@ call(Request) ->
Ref = erlang:monitor(process,?SERVER),
receive {'DOWN', Ref, _Type, _Object, noproc} ->
erlang:demonitor(Ref),
{ok,_} = start(),
case start() of
{ok,_} -> ok;
{error,{already_started,_}} -> ok
end,
call(Request)
after 0 ->
?SERVER ! {self(),Request},
Expand Down

0 comments on commit 05e49fe

Please sign in to comment.