question about "active" option (regarding gen_tcp)

Luke Gorrie luke@REDACTED
Wed Nov 7 19:24:18 CET 2001


Rick Pettit <rpettit@REDACTED> writes:

> I have a concurrent TCP server which spawns a new process every time
> gen_tcp:accept() returns.  I call gen_tcp:listen() and set active to
> true, such that tcp packets arrive as messages in my mailbox.
> 
> I had hoped to call gen_tcp:controlling_process() immediately after my
> call to accept, so that any TCP packets for that connection will be sent
> to the spawned processes mailbox.
> 
> I fear that there is a race condition between the call to accept and the
> call to controlling_process (which means the parent may receive TCP
> packets in its mailbox instead of the child).

You could accept the socket with {active, false}, then call
controlling_process, and then signal the child to call
inet:setopts(MySocket, [{active, true}]). That should do the trick.

Here's an example:

  -module(atomicsock).

  -export([go/2, helper/1]).

  go(IP, Port) ->
      {ok, S} = gen_tcp:connect(IP, Port, [list, {active, false}]),
      Helper = spawn_link(?MODULE, helper, [S]),
      gen_tcp:controlling_process(S, Helper),
      Helper ! go,
      dump("Parent").

  helper(S) ->
      receive go -> true end,
      inet:setopts(S, [{active, true}]),
      dump("Helper").

  dump(Name) ->
      receive
          Msg ->
              io:format("~s got ~p~n", [Name, Msg]),
              dump(Name)
      after 1000 -> true
      end.

Cheers,
Luke




More information about the erlang-questions mailing list