[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