diff options
author | Björn Gustavsson <[email protected]> | 2011-09-27 08:51:51 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-09-27 09:50:10 +0200 |
commit | bc4362edacedb40c6edb9e855aa234c066b8292f (patch) | |
tree | 769589b666af1003c0450d75674072654cf3e86b /lib/stdlib/src | |
parent | e423e12e8ad87348ca6c583b0ebdbe5de2aefc6f (diff) | |
download | otp-bc4362edacedb40c6edb9e855aa234c066b8292f.tar.gz otp-bc4362edacedb40c6edb9e855aa234c066b8292f.tar.bz2 otp-bc4362edacedb40c6edb9e855aa234c066b8292f.zip |
beam_lib: Handle rare race in the crypto key server functionality
In rare circumstances, there can be a race when the crypto key server
is started by beam_lib:crypto_key_fun/1 shortly after stopping it
using beam_lib:clear_crypto_key_fun/0. The race occurs because
the crypto key server first sends back the reply to the calling
process, then terminates. (The race is probably more likely to happen
on CPUs with hyper threading.)
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r-- | lib/stdlib/src/beam_lib.erl | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl index d9c645d787..fdfbb2e998 100644 --- a/lib/stdlib/src/beam_lib.erl +++ b/lib/stdlib/src/beam_lib.erl @@ -893,13 +893,17 @@ call_crypto_server(Req) -> gen_server:call(?CRYPTO_KEY_SERVER, Req, infinity) catch exit:{noproc,_} -> - start_crypto_server(), - erlang:yield(), - call_crypto_server(Req) + %% Not started. + call_crypto_server_1(Req); + exit:{normal,_} -> + %% The process finished just as we called it. + call_crypto_server_1(Req) end. -start_crypto_server() -> - gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []). +call_crypto_server_1(Req) -> + gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []), + erlang:yield(), + call_crypto_server(Req). -spec init([]) -> {'ok', #state{}}. |