[zeromq-dev] zmq_term() blocks in 2.1
chris
csrl at gmx.com
Thu Jan 13 11:02:59 CET 2011
Martin Sustrik <sustrik <at> 250bpm.com> writes:
>
> Hi Chris,
>
> > Not strictly relevant to this thread, but FYI, the erlang bindings
> > implementation at http://github.com/csrl/erlzmq supports this non-blocking
> > behavior. If any sockets are still open in the context, the zmq_term()
wrapper
> > returns EAGAIN and all sockets return ETERM.
> >
> > It was necessary to implement this in the erlang bindings, as blocking calls
> > can not be allowed in erlang port drivers, as that would cause the erlang vm
to
> > freeze.
> >
> > It works well, and would be great if the concept makes it into the main 0MQ
> > implementation.
>
> So you are running zmq_term() in background thread, right? And there's a
> way to wait while it finishes before exiting the application, right?
For simplicity, the port driver doesn't handle any threads itself. And it never
actually calls a zmq library function that could block indefinitely.
So instead, the driver's zmq_term implementation marks the context terminated at
the driver level, which causes any erlang process socket owners to unblock (if
currently blocked) with eterm, and any subsequent calls into the driver also
fail with eterm (excepting zmq_close of course - I believe I've wrapped that
correctly). But the driver itself will never call zmq library's zmq_term if a
socket is open - this isn't a problem as it must track that information anyway.
If the context owner chooses to exit while zmq_term is still returning EAGAIN,
then the driver closes all sockets itself and finally calls zmq_term once they
are closed. Of course its final call of zmq_term may still yet block according
any of the previously open socket's ZMQ_LINGER setting. That may be an
undesirable attribute for these bindings. I haven't yet had the need to address
it. I consider that use invalid any way.
As you suggest, a background thread calling zmq_term may be interesting.
chris
More information about the zeromq-dev
mailing list