[omniORB] From COM to CORBA...

Duncan Grisby dgrisby@uk.research.att.com
Mon, 12 Mar 2001 12:36:33 +0000

On Tuesday 27 February, "Len Holgate \(Mail List Account\)" wrote:

[... servant locators are less efficient than the active object

> But surely the point is that now the ORB isn't doing it for you. Of course
> the ORBs implementation of an object id to servant map may be more efficient
> than the servant locator thing shown in the example. I must admit I haven't,
> yet, gone digging in the ORB code to see how a POA that maintains an active
> object map works, or where exactly in the call sequence a servant locator
> hooks in, but it would seem - from the outside at least - that the sensible
> thing to do would be have a servant locator type thing managing the active
> object map and simply allow users to plug their own code in to replace this
> if they require. From the outside, I cant see why it would be less efficient
> to use a servant locator than not to use one - depending, of course, of the
> relative efficiency of the actual active object map replacement.... I'm
> curious now, I'm going to have to go and take a look.

In omniORB, things work a little differently from the obvious way of
implementing the spec. The spec would have you believe that the way
the ORB dispatches a request is first to find the object's POA, then
determine whether the POA has an active object map or not, look in the
map if it's there, then try a servant manager if the object hasn't
been found yet. omniORB doesn't work like that.

omniORB has a single active object map, implemented as a hash table,
shared between all POAs. When a request comes in, the first thing it
does is try to find the object in the hash table. If it finds the
object, it dispatches the request to the object without having to do a
separate POA look-up (the dispatch involves the POA, but the entry in
the hash table gives you the POA as well as the servant). This means
that the common case that the object is in the map is very quick. If
the object is not in the map, omniORB then has to find the POA based
on its name, and see if there is a servant manager available.

So, in omniORB, any arrangement other than using an active object map
is guaranteed to be slower, although the overhead is extremely small.

> Out of interest, since one usually activates the object, lets the POA manage
> it for you and releases the extra reference straight away, under what
> circumstances are these references within the server process ever used for
> much apart from counting the single reference from the POA to the servant?

As well as the possibility Stefan mentioned, CORBA allows you to
activate a single servant as multiple CORBA objects. In that case, the
POA (or POAs) holds more than one reference to the servant. The
important thing to realise is that the life cycle of a CORBA object is
totally unrelated to the life cycle of a servant object.

> Given that I didnt see the point of the internal ref, and the example wasnt
> using it, I don't find it confusing or ugly ;) The single reference count is
> now the reference count that maintains the servant object's lifetime. Seems
> far more elegant and sensible to me :)

The point remains that that was not the intention of the designers of
the C++ mapping. In other languages, Python for example, there is no
servant reference count exposed to the application. In Python, it's
impossible to implement the scheme you use.

> > So now the only reference to the servant is held by the POA. Then when
> > you deactivate the object, the servant is deleted immediately.
> Well, at some point after the the method call that does the deactivate
> returns... Or at least that's what it says in the book.

Well, OK. You should certainly treat it as though it is deleted
immediately, though.

> A addrefs the object before it hands out the reference to B. It's one of the
> "rules of com" that when you give out an interface pointer you've addref'd
> it before you give it. That way B only has to release it when it's done. I
> agree that without support for this kind of thing in the marshalling code it
> gets a little hairy...

It's especially hairy since A can't just addref the object -- it has
to say "I'm addreffing this on behalf of B", otherwise the object
can't track who owns references to it.

> Agreed. What I'm looking for is how you DO do it if you decide that it IS
> what you need and you happen to be in CORBA-land. Almost all the articles
> and books I've read seem to imply that you just design your way out of the
> problem because reference counting is inherently evil... It seems to me,
> from my COM background, that the only reason that that stance is taken is
> because CORBA can't do it well...

I think the truth is somewhere in-between the two stances. The thing
is that reference counting is much harder to do within the CORBA
object model than within the COM one. I don't mean harder for the
end-user, but harder for the person implementing the reference
counting. COM has a simple model where interface pointers are passed
around -- there is never a concern about things like the CORBA naming
service returning a sequence of 1000 objects, all of which would need
to be addreffed.

One could choose to see this as a limitation of the CORBA object
model, but I see it as a trade-off with the greater flexibility and
expressive power CORBA's model gives you.

I do agree, however, that it would be nice if there were some articles
or books which addressed reference counting in CORBA, from a CORBA



 -- Duncan Grisby  \  Research Engineer  --
  -- AT&T Laboratories Cambridge          --
   -- http://www.uk.research.att.com/~dpg1 --