[erlang-bugs] Deadlock when doing gen_tcp:send on Win32

Colm Dougan <>
Fri Feb 13 22:27:14 CET 2009


I have encountered a problem when doing gen_tcp:send on Win32.  The
problem is easy to replicate on my setup.  I suspect this is a bug in
erlang on Win32 but I can't be sure  I have unfortunately been unable
to replicate this in a stand-alone program I can send you but I have
rebuilt erlang (12B-5) and added some extra trace.

Here is what I know about the problem :

* it seems to occur when there is a fast sender
* it seems to *only* occur when gen_tcp:send on a large payload
represented as an iolist (in this case the output of calling
zlib:deflate on a fairly uncompressible 60k binary).  When I call
iolist_to_binary before calling gen_tcp:send I can't seem to replicate
the problem.  I can't explain why the iolist_to_binary helps.

Here is the output of some extra trace I added into
erts/emulator/drivers/common/inet_drv.c :

tcp_sendv(4113): s=61333, len=2080 Send failed, queuing
tcp_sendv(4113): sz=0, ev->size=61333, desc->high=8192
tcp_sendv(4113): s=61598, len=2080 Send failed, queuing
tcp_sendv(4113): sz=0, ev->size=61598, desc->high=8192
tcp_sendv(4113): s=2080, len=61570 sender forced busy
tcp_sendv(4113): sz=1598, ev->size=61570, desc->high=8192

My connection just hangs at that point.  On the erlang side the
gen_tcp:send call never returns.  It just blocks forever.

When I do iolist_to_binary on the iolist before calling gen_tcp:send I
get similar output but it never hangs.

I realize this is a bit sketchy but the app is fairly involved and I
can't seem to boil the problem down to a self-contained replication
scenario.  I'd be happy to work with anyone who wants me to add more
trace or to look at my setup (via VPN access or whatever).   Also, if
this rings any bells at all I'd be grateful for any clues people can
give me so I can try to track it down further.

A question: I've mentioned that the work-around seems to be to call
iolist_to_binary before calling gen_tcp:send.  I'm more than happy
with that as a work-around as long as it won't be too expensive.  Do
people think it would be expensive to call iolist_to_binary on an
iolist of (approx) 15 x 4000 byte binaries before calling gen_tcp:send
when there are many connections in the mix (hundreds or possibly
thousands of connections) *or* does calling erlang:port_command do
essentially the same work anyway before passing it down to inet_drv?


More information about the erlang-bugs mailing list