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;
|
true -> true;
|
||||||
once -> {once, false}
|
once -> {once, false}
|
||||||
end,
|
end,
|
||||||
OwnerRef = erlang:monitor(process, Owner),
|
State = #state{ rx = Rx, tx = Tx, owner = Owner,
|
||||||
State = #state{ rx = Rx, tx = Tx, owner = Owner, owner_ref = OwnerRef,
|
|
||||||
tcp_sock = TcpSock, active = Active },
|
tcp_sock = TcpSock, active = Active },
|
||||||
|
|
||||||
case gen_server:start_link(?MODULE, [State], []) of
|
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:call(Noise, {controlling_process, self(), NewPid}, 100).
|
||||||
|
|
||||||
%% -- gen_server callbacks ---------------------------------------------------
|
%% -- gen_server callbacks ---------------------------------------------------
|
||||||
init([State]) ->
|
init([#state{owner = Owner} = State]) ->
|
||||||
{ok, State}.
|
OwnerRef = erlang:monitor(process, Owner),
|
||||||
|
{ok, State#state{owner_ref = OwnerRef}}.
|
||||||
|
|
||||||
handle_call(close, _From, S) ->
|
handle_call(close, _From, S) ->
|
||||||
{stop, normal, ok, 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 }};
|
{noreply, S#state{ tcp_sock = closed }};
|
||||||
handle_info({'DOWN', OwnerRef, process, _, normal},
|
handle_info({'DOWN', OwnerRef, process, _, normal},
|
||||||
S = #state { tcp_sock = TS, owner_ref = OwnerRef }) ->
|
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 }};
|
{stop, normal, S#state{ tcp_sock = closed, owner_ref = undefined }};
|
||||||
handle_info({'DOWN', _, _, _, _}, S) ->
|
handle_info({'DOWN', _, _, _, _}, S) ->
|
||||||
%% Ignore non-normal monitor messages - we are linked.
|
%% Ignore non-normal monitor messages - we are linked.
|
||||||
@ -190,3 +190,8 @@ flush_tcp(Pid, TcpSock) ->
|
|||||||
flush_tcp(Pid, TcpSock)
|
flush_tcp(Pid, TcpSock)
|
||||||
after 1 -> ok
|
after 1 -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
close_tcp(closed) ->
|
||||||
|
ok;
|
||||||
|
close_tcp(Sock) ->
|
||||||
|
gen_tcp:close(Sock).
|
||||||
|
@ -81,6 +81,15 @@ noise_dh25519_test_() ->
|
|||||||
end
|
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() ->
|
setup_dh25519() ->
|
||||||
%% Generate a static key-pair for Client and Server
|
%% Generate a static key-pair for Client and Server
|
||||||
SrvKeyPair = enoise_keypair:new(dh25519),
|
SrvKeyPair = enoise_keypair:new(dh25519),
|
||||||
@ -93,6 +102,52 @@ setup_dh25519() ->
|
|||||||
{Configurations, SrvKeyPair, CliKeyPair}.
|
{Configurations, SrvKeyPair, CliKeyPair}.
|
||||||
|
|
||||||
noise_test(Conf, SKP, CKP) ->
|
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),
|
Protocol = enoise_protocol:from_name(Conf),
|
||||||
Port = 4556,
|
Port = 4556,
|
||||||
|
|
||||||
@ -114,10 +169,21 @@ noise_test(Conf, SKP, CKP) ->
|
|||||||
receive
|
receive
|
||||||
{noise, _, <<"Goodbye!">>} -> ok
|
{noise, _, <<"Goodbye!">>} -> ok
|
||||||
after 100 -> error(timeout) end,
|
after 100 -> error(timeout) end,
|
||||||
|
#{ econn => EConn
|
||||||
|
, tcp_sock => TcpSock
|
||||||
|
, echo_srv => EchoSrv }.
|
||||||
|
|
||||||
enoise:close(EConn),
|
noise_monitor_test(Conf, SKP, CKP) ->
|
||||||
echo_srv_stop(EchoSrv),
|
#{ econn := {enoise, EConnPid}
|
||||||
ok.
|
, 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) ->
|
echo_srv_start(Port, Protocol, SKP, CPub) ->
|
||||||
Pid = spawn(fun() -> echo_srv(Port, Protocol, SKP, CPub) end),
|
Pid = spawn(fun() -> echo_srv(Port, Protocol, SKP, CPub) end),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user