How to delete servants?
Duncan Grisby
duncan at grisby.org
Fri Dec 18 12:41:57 GMT 2015
On Thu, 2015-12-10 at 19:53 +0100, szyk100 wrote:
[...]
> [[ questions about _var and _ptr ]]
> 1. Why can't I return _var from function? I must alvays return _ptr.
Because those are the rules. When an item is the return value of an
operation, ownership of the item is transferred to the caller.
If you have a _var in your code, and you need to return the item, you
can use the _retn() function:
Thing_ptr myOperation() {
Thing_var thing = createMyThing();
return thing._retn();
}
> 2. Is it safe to send _var to function as argument/parameter?
Yes.
> 3. Why don't I need call CORBA::release when I get _ptr as argumrnt/parameter?
Because those are the rules. When an item is used in a parameter, the
caller keeps ownership of it.
> Now I show step by step how I create, use and delete RoomControllerImp
That's far too much code to comment on all of it, but I'll give you some
hints...
[...]
> mUser->mUserObjectID = mPoa->activate_object(mUser);
You haven't shown your class definition, but I'm assuming mUserObjedID
is a PortableServer::ObjectId_var ? It should be so that it releases
the object id when appropriate.
> TCzat::User_var lUserPtr = mUser->_this();
> mUser->mRoomController = mRoom->joinUser(lUserPtr);
> //CORBA::release(lUserPtr);
lUserPtr is a _var, so it releases the contained pointer when it goes
out of scope. It is indeed therefore wrong to call CORBA::release() on
it.
[...]
> // add user to internal list
> mUsers.append(::TCzat::User::_duplicate(aUser));
I don't know what the type of mUsers is, but since you are calling
_duplicate on the object references as they go it, it's important that
whatever mUsers is calls CORBA::release on the object references at some
point.
[...]
> // call all users to add user to they list
> for(int i = 0; i < mUsers.length(); ++i)
> mUsers[i]->addUser(::TCzat::User::_duplicate(aUser));
Assuming addUser() is an IDL-defined operation, this is wrong. The
caller retains ownership of the function parameters, so you should not
call _duplicate.
> Room_var lRoom = _this();
> RoomControllerImp* lController = new RoomControllerImp(TCzat::Room::_duplicate(lRoom), mPoa);
You shouldn't duplicate lRoom here. For consistency with IDL-defined
operations, you should just pass in lRoom. if RoomControllerImp needs to
keep a reference to it, it should in the RoomControllerImp constructor
that you do the _duplicate.
The lController servant object is created with reference count 1.
> PortableServer::ObjectId_var lControllerID = mPoa->activate_object(lController);
The POA takes a reference to the servant so lController now has
reference count 2.
> //mRoomControllers.append(lControllerID);
>
> RoomController_ptr lControllerPtr = lController->_this();
> return lControllerPtr;
The lController servant reference has been leaked. You need to call
_remove_ref() on it after you call mPoa->activate_object(). One way to
achieve that is to use a servant _var type with
PortableServant::Servant_var<>.
[...]
> void WinMainC::returnPressed()
> {
> mUser->sendMessage(CORBA::wstring_dup(mUser->mName.toStdWString().c_str()), CORBA::wstring_dup(mRoom->name()), CORBA::wstring_dup(ui->mMessage->text().toStdWString().c_str()));
As with object reference parameters, the caller retains ownership of the
wstring parameters. It is therefore wrong to call CORBA::wstring_dup()
here.
[...]
> UserImp::mRoomController is TCzat::RoomController_ptr, so I call CORBA::release() in next function.
>
> void UserImp::destroy()
> {
> TCzat::User_var lUserPtr = _this();
> mRoomController->removeUser(lUserPtr);
> mRoomController->destroy();
> CORBA::release(mRoomController);
> }
I would expexct mRoomController to be a RoomController_var, so there
would be no need to explicitly call CORBA::release() on it.
Assuming that this destroy() method is meant to get rid of the CORBA
object, you need to call poa->deactivate_object() in it.
Duncan.
--
-- Duncan Grisby --
-- duncan at grisby.org --
-- http://www.grisby.org --
More information about the omniORB-list
mailing list