Move monitor of owner into the connection process. Add test case.
This commit is contained in:
parent
c3bdb02e53
commit
cff15e0bfb
@ -33,8 +33,7 @@ start_link(TcpSock, Rx, Tx, Owner, {Active0, Buf}) ->
|
||||
true -> true;
|
||||
once -> {once, false}
|
||||
end,
|
||||
OwnerRef = erlang:monitor(process, Owner),
|
||||
State = #state{ rx = Rx, tx = Tx, owner = Owner, owner_ref = OwnerRef,
|
||||
State = #state{ rx = Rx, tx = Tx, owner = Owner,
|
||||
tcp_sock = TcpSock, active = Active },
|
||||
|
||||
case gen_server:start_link(?MODULE, [State], []) of
|
||||
@ -67,8 +66,9 @@ controlling_process(Noise, NewPid) ->
|
||||
gen_server:call(Noise, {controlling_process, self(), NewPid}, 100).
|
||||
|
||||
%% -- gen_server callbacks ---------------------------------------------------
|
||||
init([State]) ->
|
||||
{ok, State}.
|
||||
init([#state{owner = Owner} = State]) ->
|
||||
OwnerRef = erlang:monitor(process, Owner),
|
||||
{ok, State#state{owner_ref = OwnerRef}}.
|
||||
|
||||
handle_call(close, _From, S) ->
|
||||
{stop, normal, ok, S};
|
||||
@ -103,7 +103,7 @@ handle_info({tcp_closed, TS}, S = #state{ tcp_sock = TS, owner = O }) ->
|
||||
{noreply, S#state{ tcp_sock = closed }};
|
||||
handle_info({'DOWN', OwnerRef, process, _, normal},
|
||||
S = #state { tcp_sock = TS, owner_ref = OwnerRef }) ->
|
||||
gen_tcp:close(TS),
|
||||
close_tcp(TS),
|
||||
{stop, normal, S#state{ tcp_sock = closed, owner_ref = undefined }};
|
||||
handle_info({'DOWN', _, _, _, _}, S) ->
|
||||
%% Ignore non-normal monitor messages - we are linked.
|
||||
@ -190,3 +190,8 @@ flush_tcp(Pid, TcpSock) ->
|
||||
flush_tcp(Pid, TcpSock)
|
||||
after 1 -> ok
|
||||
end.
|
||||
|
||||
close_tcp(closed) ->
|
||||
ok;
|
||||
close_tcp(Sock) ->
|
||||
gen_tcp:close(Sock).
|
||||
|
@ -81,6 +81,15 @@ noise_dh25519_test_() ->
|
||||
end
|
||||
}.
|
||||
|
||||
noise_monitor_test_() ->
|
||||
{setup,
|
||||
fun() -> setup_dh25519() end,
|
||||
fun(_X) -> ok end,
|
||||
fun({[T|Tests] = _Tests, SKP, CKP}) ->
|
||||
[ {T, fun() -> noise_monitor_test(T, SKP, CKP) end} ]
|
||||
end
|
||||
}.
|
||||
|
||||
setup_dh25519() ->
|
||||
%% Generate a static key-pair for Client and Server
|
||||
SrvKeyPair = enoise_keypair:new(dh25519),
|
||||
@ -93,6 +102,52 @@ setup_dh25519() ->
|
||||
{Configurations, SrvKeyPair, CliKeyPair}.
|
||||
|
||||
noise_test(Conf, SKP, CKP) ->
|
||||
#{econn := EConn, echo_srv := EchoSrv} = noise_test_run(Conf, SKP, CKP),
|
||||
enoise:close(EConn),
|
||||
echo_srv_stop(EchoSrv),
|
||||
ok.
|
||||
|
||||
noise_test_run(Conf, SKP, CKP) ->
|
||||
{Pid, MRef} = spawn_monitor_proxy(
|
||||
fun() -> noise_test_run_(Conf, SKP, CKP) end),
|
||||
receive
|
||||
{Pid, #{} = Info} ->
|
||||
Info#{proxy => Pid, proxy_mref => MRef}
|
||||
after 5000 ->
|
||||
erlang:error(timeout)
|
||||
end.
|
||||
|
||||
spawn_monitor_proxy(F) ->
|
||||
Me = self(),
|
||||
spawn_monitor(fun() ->
|
||||
MRef = erlang:monitor(process, Me),
|
||||
Res = F(),
|
||||
Me ! {self(), Res},
|
||||
proxy_loop(Me, MRef)
|
||||
end).
|
||||
|
||||
proxy_loop(Parent, MRef) ->
|
||||
receive
|
||||
{Parent, Ref, F} when is_function(F, 0) ->
|
||||
Parent ! {Ref, F()},
|
||||
proxy_loop(Parent, MRef);
|
||||
{'DOWN', MRef, process, Parent, _} ->
|
||||
done
|
||||
end.
|
||||
|
||||
proxy_exec(P, F) when is_function(F, 0) ->
|
||||
R = erlang:monitor(process, P),
|
||||
P ! {self(), R, F},
|
||||
receive
|
||||
{R, Res} ->
|
||||
Res;
|
||||
{'DOWN', R, _, _, Reason} ->
|
||||
erlang:error(Reason)
|
||||
after 5000 ->
|
||||
erlang:error(timeout)
|
||||
end.
|
||||
|
||||
noise_test_run_(Conf, SKP, CKP) ->
|
||||
Protocol = enoise_protocol:from_name(Conf),
|
||||
Port = 4556,
|
||||
|
||||
@ -114,10 +169,21 @@ noise_test(Conf, SKP, CKP) ->
|
||||
receive
|
||||
{noise, _, <<"Goodbye!">>} -> ok
|
||||
after 100 -> error(timeout) end,
|
||||
#{ econn => EConn
|
||||
, tcp_sock => TcpSock
|
||||
, echo_srv => EchoSrv }.
|
||||
|
||||
enoise:close(EConn),
|
||||
echo_srv_stop(EchoSrv),
|
||||
ok.
|
||||
noise_monitor_test(Conf, SKP, CKP) ->
|
||||
#{ econn := {enoise, EConnPid}
|
||||
, proxy := Proxy
|
||||
, tcp_sock := TcpSock } = noise_test_run(Conf, SKP, CKP),
|
||||
try proxy_exec(Proxy, fun() -> exit(normal) end)
|
||||
catch
|
||||
error:normal ->
|
||||
receive after 100 ->
|
||||
false = is_process_alive(EConnPid)
|
||||
end
|
||||
end.
|
||||
|
||||
echo_srv_start(Port, Protocol, SKP, CPub) ->
|
||||
Pid = spawn(fun() -> echo_srv(Port, Protocol, SKP, CPub) end),
|
||||
|
Loading…
x
Reference in New Issue
Block a user