[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),
end.
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