[omniORB] Thread-safety of Any with local calls

Chris Newbold cnewbold@laurelnetworks.com
Mon Sep 23 20:32:00 2002


I've run into some rather surprising thread-safety issues with Any and
local calls (this is with omniORB 3.0.5).

We've got a simple messaging system where messages, which look like
this...

    // IDL
    
    struct Message {
        string topic;
        any contents;
    };
    
    interface Agent {
    	void Publish(in Message m);
    };
    
    interface Observer {
    	void PushMessage(in Message m);
    };
    
...are sent to a central agent by various parts of our system. The
central agent turns around and forwards the messages to various
observers, which may be in-process or remote.

The central agent pushes a copy of each message received into a single
buffer; pointers to this message are then pushed onto queues for each
observer with a registered interested in the message's topic. Background
threads, one per observer, run through the per-observer queues and make
a call to deliver the message (effectively passing a reference to the
single copy of the message in the central buffer).

This all works fine until we register two observers interested in the
same messages and which are both in-process. When the agent makes a call
to deliver a message, it looks like the observers each get a reference
to the _same_ Any that's in the agent's central buffer!

Now, the first thing that each observer does is attempt to extract the
contents of the message from the Any. As it turns out, extraction from
an Any is _not_ thread safe, so the two observers wind up corrupting the
buffered message and one or both get CORBA::MARSHAL.

Taken in isolation, I can understand the rational for the optimizations
that are causing these problems: just passing a reference to the
caller's Any for local calls and not having locks in the Any
implementation.

However, the combination seems to result in asymmetric behavior for
in-process and remote calls. Further more, the only way for me to avoid
this problem is to make and buffer a unique copy of the message for each
observer. (I can't copy the message just prior to delivery since even
copying an Any appears not to be thread-safe.) This is an unacceptable
overhead in performance and memory...

Is this a bug or a feature? :-)


-- 
====( Chris Newbold  <cnewbold@laurelnetworks.com>
)==========================
      Laurel Networks, Inc. voice: +1 412 809 4200 fax: +1 412 809 4201
"If you fool around with a thing for very long you will screw it up."
--Murphy
------------------------------------------------------------------------------