[erlang-questions] Non-blocking sends in gen_tcp?

Matthias Lang <>
Thu Mar 12 21:49:56 CET 2009


On Wednesday, March 11, Cayle Spandon wrote:
> Does gen_tcp provide a mechanism for non-blocking sends, similar to the
> traditional send and select/poll calls in Unix, in the following sense:

Short answer: "no".

Your post almost boils down to "I want to do this the same way as I do
it in C. I'm aware of some ways it could be done in Erlang, but I
specifically don't want to use any of those for mostly unspecified reasons."
I.e. you may be unnecessarily tying one hand behind your back.

On the other hand, there are some things which Just Can't Be Done with
gen_tcp:send(), for instance

  1. You have two things you want to send

  2. You give them both to gen_tcp:send(), which blocks
     (in C, you might have successfully sent the first, but gotten an
     EWOULDBLOCK or EAGAIN or whatever on the second and thus not sent it)

  3. Something else happens, e.g. a timer expires, and you now want to
     send a third item but not the second. But you can't snatch the
     second back from gen_tcp:send()
     (in C, the second item was still under your control)

and it could be that you want to do something like that. If that's so,
I think you're SOL.

It sounds like you already found this discussion:

  http://erlang.org/pipermail/erlang-questions/2008-November/039791.html

which is pretty much everything I know about the subject. There are
other people who know more, they may or may not find time to write
something about it. If you want to dig, I think you'll need to go
lower than prim_inet, i.e to the somewhat daunting

  erts/emulator/drivers/common/inet_drv.c

It's possible I've missed something.

Matt

--------------------

> -1- When you call gen_tcp:send() with N bytes and flow-control kicks in,
> gen_tcp:send()returns immediately (i.e. does not block, not even for some
> small time-out). The return value indicates that flow-control was invoked
> and gives some indication of what subset of bytes was accepted (e.g. by
> returning the remaining unsent binary). This is similar to Unix send()
> returning EAGAIN.

> -2- Some mechanism to inform the sending process that the socket is ready to
> send more data, e.g. an Erlang message. This is similar to Unix select()
> reporting that a socket is ready-to-send.
> 
> I have considered the option of creating an Erlang process dedicated to
> sending messages over the socket and using blocking gen_tcp:send calls in
> that process. For various reasons  (related to the fact that a send may have
> to be interruped by some other activity) this is not an option for me.
> 
> I found some references to the prim_inet module on Google, but evidently
> that is not an officially documented module.
> 
> PS - My apologies if this question has already been answered. I googled the
> topic and found many discussions but not quite the answer.



More information about the erlang-questions mailing list