[erlang-questions] Re: TCP port sends EXIT message
Matthias Lang
matthias@REDACTED
Wed Dec 15 21:00:15 CET 2010
On Wednesday, December 15, Per Andersson wrote:
> I realized that this happened because the acceptor is shutdown after it
> calls controlling_process. I, erroneously, thought that controlling_process
> would actually transfer all control and ownership of the socket to a new
> process. This does not seem to be the case, the docs state only that the
> new owner will receive messages.
gen_tcp:controlling_process() transfers both "control" (who receives
messages) and "ownership" (which process is linked to the port).
I took a guess at what you were trying to do and wrote a minimal,
self-contained example that compiles. The socket does not die
when the process which originally owned it died:
-module(per_a).
-export([go/0]).
go() ->
erlang:process_flag(trap_exit, true),
{ok, L} = gen_tcp:listen(5555, [{active, false}, {reuseaddr, true}]),
spawn(fun connect/0),
Self = self(),
Acceptor_pid = spawn_link(fun() -> acceptor(L, Self) end),
receive
{Acceptor_pid, Socket} ->
exit(Acceptor_pid, kill),
receive
{'EXIT', Acceptor_pid, _} -> ok
end,
io:fwrite("This process is ~p\n", [self()]),
io:fwrite("The acceptor pid, ~p is now dead (process_info=~p)\n",
[Acceptor_pid, erlang:process_info(Acceptor_pid)]),
io:fwrite("The socket is still alive (port_info=~p)\n",
[erlang:port_info(Socket)]),
{ok, Data} = gen_tcp:recv(Socket, 0),
io:fwrite("Here's some freshly received socket data: ~p\n", [Data]),
gen_tcp:close(Socket),
gen_tcp:close(L)
end.
connect() ->
{ok, S} = gen_tcp:connect(localhost, 5555, []),
ok = gen_tcp:send(S, "hello world\n"),
Ref = make_ref(), receive Ref -> done end. % hang forever
acceptor(L, Parent) ->
{ok, S} = gen_tcp:accept(L),
ok = gen_tcp:controlling_process(S, Parent),
Parent ! {self(), S},
Ref = make_ref(), receive Ref -> done end. % hang forever
--------------------
Here's the output:
| 2> per_a:go().
| This process is <0.31.0>
| The acceptor pid, <0.39.0> is now dead (process_info=undefined)
| The socket is still alive (port_info=[{name,"tcp_inet"},
| {links,[<0.31.0>]},
| {id,2046},
| {connected,<0.31.0>},
| {input,0},
| {output,0}])
| Here's some freshly received socket data: "hello world\n"
|
The question now is: what are you doing differently? Can you post a
minimal, self-contained example which compiles, runs and demonstrates
the socket dying unexpectedly?
Matt
More information about the erlang-questions
mailing list