[zeromq-dev] Cleaning-up context creation API

john skaller skaller at users.sourceforge.net
Thu Feb 16 01:07:16 CET 2012

On 16/02/2012, at 9:57 AM, Pieter Hintjens wrote:
> * zmq_ctx_init and zmq_ctx_term
> * zmq_ctx_peek and zmq_ctx_poke to get/set options
> * explicit option settings for ZMQ_IOTHREADS and ZMQ_THREADSAFE

The thread_safe variant will work with poke, but ZMQ_IOTRSEADS won't
unless you do:

> And internally this would create the context lazily, only when the
> first socket is created (so the IOTHREADS can be applied then).

which is a bit risky IMHO. The reason is: you're delaying error detection
in the launching of the threads. That makes it impossible to return
an error code.

close() on async sockets has the same bug (I mean posix sockets not 0MQ ones).

On naming: the theme seems to be using an OO friendly naming scheme.
Seems cool. So basically *except* for constructors 


would bind in an OO language to 

	zmq::method(object, other args)


	object->other args

So if we're going for consistency .. "init" sucks. zmq_ctx_init creates
a ctx. but zmq_msg_init doesn't, it initialises an existing one.

Similarly, "term" and "close". There's a difference between closing
an underlying resource but leaving the object in a coherent state,
and destroying the object (which may or may not destroy the
underlying resource: eg .. ref counted messages).

If you're going to make a new, consistent API, the constructor/destructor
naming should be consistent too. So should the argument usage
and semantics. It's not really very nice that contexts and sockets are
opaque, copyable pointer types, whilst "messages" are structs
containing pointers.

Actually I think message should be heap allocated like everything else.
In a well written program, you can still move the buffers around so
you don't need a fresh message container thing for every 
new blob of data. [** Felix binding does that anyhow, it's just
easier for the clients and malloc is fast]

Finally, the options interface SUCKS for C clients. It's ok for language
bindings other than C. If I had to use the get/set socket options much
I'd be wrapping every one in a function to avoid the ugly creation
of blobs.

I think it's a "cheat" to pretend that 0MQ only has a few functions in it's
API. Every socket type is actually a distinct factory:

	zmq_socket(ctx, ZMQ_PUB);

this is just cheating to make it look like 0MQ is simple. The right way is:

	zmq_socket_pub (ctx);

The first method assumes it makes sense to make the call parametric.
I think that's not the case: zmq sockets have distinct types, and you can't
create a sane network topology where the socket types are parametric.
[The endpoints would be parametric, that makes sense]

yeah, I know Posix does this kind of crud, but it's constrained by historical

I guess in summary: if you're going to make a new C API, and deprecate the old
one, we might as well re-examine the whole structure. C interfaces are just 
hard because the language is so weak. It's not entirely clear it's worth bothering.
Might be better to focus on good bindings for other languages, especially C++.

Most networking applications could use C++ instead of C. In fact they can't
really use 0MQ unless they have C++ (since the actual library is C++ :)

A simple "C with classes" interface to 0MQ (no exceptions or anything) would
be so much easier (constructors and destructors alone give significant

YMMV: no point doing a new API with only a couple of minor changes.

john skaller
skaller at users.sourceforge.net

More information about the zeromq-dev mailing list