[erlang-questions] gen_tcp:recv and hairloss

Kevin q2h46uw02@REDACTED
Sat Nov 8 17:23:29 CET 2008

using controlling_process sounds like a great solution, but I've tried 
that.  In the cleaned up code below, I try to assign
the socket to the Fsm, but I get the error {error,not_owner}.

You'd think that if only the controlling process could read from the 
socket, than I should never have gotten anywhere, since
the only process that is actually reading from the socket is not the 
owner either!

You'd think that in a language where threading and networking are king, 
they would mention in the docs that, oh, btw, only
the owning process can call recv on a socket, but sending and closing, 
oh you can do that anytime you want.

Another thing, the docs for controlling_process just give the impression 
that the owning process merely is the process that
receives messages from the socket, that is, unless you set {active, false}

loop(Sock, Fsm) ->
    case gen_tcp:recv(Sock, 0, ?RECV_TIMEOUT) of %% this works!
    {ok, Request} ->
          ok = gen_tcp:controlling_process(Sock, Fsm), %% {error,not_owner}
          ok = gen_fsm:send_event(Fsm, {Request, Sock}),
          loop(Sock, Fsm)
    {error, Reason} ->
            ok = gen_tcp:close(Sock),

Christian chsu79-at-gmail.com |erlang| wrote:
>> Basically I can't read from the socket unless I come back up out of the
>> Fsm and let the same loop get the next line.  What is so
>> special about the gen_server process that can *read* from the socket and
>> the fsm process that cant?!?
> The process that accepts the connection is the owner of that socket, also
> called the controlling process. Only the owner can recv.  You can
> transfer ownership
> using gen_tcp:controlling_process/2 (from the current owner).
> What I typically do is to follow the design where in your case the
> gen_fsm would start out
> as an ordinary process spawned by proc_lib, then using
> gen_fsm:enter_loop when a connection
> has been accepted.
> The server process will then start these acceptor processes, wait for
> them to report that a aconnection
> has been accepted, and thus start a new acceptor process.
> This always feels a bit clunky to set up, but the pay off in cleaner
> design makes it worth it. Your server
> process is never blocked. While an acceptor process is looping around
> in gen_tcp:accept until a connection
> is accepted, the server process is free to accept calls and casts for
> commands sent to or from already
> accepted connections.

More information about the erlang-questions mailing list