[omniORB] strange behavior of '_this()' method

Michael omniorb at bindone.de
Wed Apr 1 15:00:42 BST 2009


Duncan Grisby wrote:
> On Wednesday 1 April, Michael wrote:
> 
>> Michael Kilburn wrote:
>>> On Tue, Mar 31, 2009 at 4:59 AM, Michael <omniorb at bindone.de> wrote:
>>>
>>>>  PortableServer::Servant servant = _poa->reference_to_servant(obj);
>>>>                servant->_remove_ref();
>>> Just being pedantic... this is better:
>>>
>>> PortableServer::Servant_var servant = _poa->reference_to_servant(obj);
>> Sorry, but no :) PortableServer::Servant is a pointer to (not a copy of)
>>  the incarnating servant in the active object map. You don't want the
>> _var class to clean that up ever (and btw it won't compile anyway
>> because PortableServer::Servant is a local corba pseudo class thingy).
> 
> You're both wrong, just in different ways :-)
> 
> The code with Servant_var won't compile, but that's because Servant_var
> is a template, not because it's wrong to use a _var type with a
> servant. This code is completely valid and does the right thing with
> _remove_ref:
> 
>   PortableServer::ServantBase_var servant = _poa->reference_to_servant(obj);
Sometimes I love CORBA :). I never thought of that in the first place,
because I really need the dynamic cast. Without checking the specs, how
would I do a dynamic cast from a PortableServer::ServantBase_var?
(I would assume
whatever_impl* that = dynamic_cast<whatever_impl*>(servant.in()))

> 
> 
>> You're confused about memory management rules here (which brings me back
>> to my previous argument about CORBA complexity and developers getting
>> confused about it :).
And obviously sometimes that includes me as well :)

>>
>> So you understand the context:
>> try
>> {
>>   PortableServer::Servant servant = _poa->reference_to_servant(obj);
>>   servant->_remove_ref();
> 
> That is a dangerous thing to do. By calling _remove_ref there, you are
> assuming that the POA is going to keep holding its reference to the
> servant. If another thread deactivates the object, you might find the
> servant being deleted from under you. It's much safer to call
> _remove_ref once you've finished using the servant, and the easiest way
> to do that is to use ServantBase_var.
Actually in my case it is not, but that's because I copy and pasted that
out of code that works differntly anyway (I use a combined approach, so
the pointer is "safe" because it is backed by a smart pointer somewhere
else). Of course, I shouldn't advise that without comments because
you're right that without these specifics it is extremely dangerous.
Knowing that _var works, I think I will change my code anyway, since it
seems more maintenance-friendly.

> 
>>   IRObject_impl* impl = dynamic_cast<IRObject_impl*>(servant);
>>   if (impl)
>>   {
>>     // do something
>>   }
>>   // there is no delete statement here, try this to crash it:
>>   // delete servant;
> 
> A delete of the servant there is wrong because the POA still holds a
> reference to the servant.
That's what I wanted to point out (but the argument was flawed  in the
first place anyway)

> 
> Cheers,
> 
> Duncan.
> 




More information about the omniORB-list mailing list