[zeromq-dev] Java API is not notifed of C++ assert failures.
Martin Sustrik
sustrik at fastmq.com
Thu Apr 2 11:32:39 CEST 2009
Vladimir & Mihaela wrote:
> Hey Martin,
>
> I agree with you that the passing of the api_thread_id as the first
> parameter for all meaningful functions (createQUeue, createExchange, bind,
> send, receive) is not neat. However, I think it's the most efficient way -
> not too many Java to C++ marshalling of params. The messaging code is
> already encapsulated and there are only a couple of places where one would
> need to pay close attention.
>
> You mention in one of the previous posts: "Constructor has to take 'number
> of threads' parameter and return N 'API' objects instead of a single one."
>
> Along these lines I could return an array of api proxies, or an ArrayList of
> proxies. In either case in Java I would need to get each of the proxies
> using code like.
>
> ApiProxy[] apiProxies = (new Jzmq(zmqHost, 2)).getProxies();
> ApiProxy api1 = apiProxies[0];
> ApiProxy api2 = apiProxies[1];
>
> or
>
> ArrayList<ApiProxy> apiProxies = (new Jzmq(zmqHost, 2)).getProxies();
> ApiProxy api1 = apiProxies.get(0);
> ApiProxy api2 = apiProxies.get(1);
>
> and then use api1 in one thread and api2 in the other.
>
> Not sure if this is neater; definitely it is less efficient.
Yuck. You are right. It looks ugly.
My feeling was that having to pass thread ID to each function is prone
to misuse. Even worse, if you pass a wrong ID it won't fail in some
clearly defined fashion, rather it'll introduce subtle synchronisation
bugs and race conditions.
You may have an experience of how difficult it is find/reproduce/fix
synchronisation problems. Being hard with mutexes and condition
variables, it's twice as hard with lock-free algorithms which move
synchronisation from kernel level to HW level - and that's what used
inside 0MQ.
Thus, we should do our best to not even allow for this kind of bug, even
if the user misuses the API.
>
> Alternatively I could create the object stubs in Java and invoke
> api_thread_t::create in the ApiProxy constructor.
>
> Jzmq jzmq = new Jzmq(zmqHost, 2);
> ApiProxy api1 = new ApiProxy(jzmq);
> ApiProxy api2 = new ApiProxy(jzmq);
>
> but in this case one would need to make sure the counter in the Jzmq
> constructor matches the number of proxies created with new. Neater, agreed.
Yes. This one copies C++ syntax. It's better IMO.
> So, which one do you prefer? Do you have any other suggestions?
There's one more possibility. There are thread-scope variables in Java
AFAIU:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html
Thus you can hold the zmq::api_thread_t object in such a variable.
Individual functions will simply use this value to access the object
tied to the current thread. Pseudocode:
// Two threads will be using the library.
z = new Zmq (2);
// Creates underlying API object and stores it in thread-scoped variable.
Zmq.InitThread ();
// Use 0MQ in a standard manner
Zmq.CreateQueue ("myqueue");
You can even do without the InitThread function. Each zmq function can
check whether the thread-scoped variable is NULL and if so, create an
api_thread_t object.
What do you think?
> WRT loading the libzmq in addition to jzmq, I just did a search for the
> error that I was getting trying to run my code and the recommended solution
> was just this. I think this will run under Unix/Linux as well without
> problems.
It can do no harm. The only issue I had whether it have actually helped.
We'll merge it in.
>
> Finally, I am not familiar with MIT licensing. Briefly, what do I need to
> do?
Just say that you are submitting your patches under MIT license. This
helps us to keep the code base free of implicit IP issues.
Cheers.
Martin
More information about the zeromq-dev
mailing list