How to delete servants?

Duncan Grisby duncan at grisby.org
Thu Dec 3 12:32:26 GMT 2015


On Thu, 2015-11-26 at 21:10 +0100, szyk100 wrote:

> [[ Problem ]]
> Problem is with memory management. In every servant class I add line to destructor:
> cout<<"XYZ deleted"<<endl;
> Where XYZ is the class name.
> But apparently no one destructor is called.

Memory management in the C++ mapping is, unfortunately, quite tricky.
The most important thing to realise is that the lifetime of object
references is totally separate from the lifetime of servants. All the
various _var types you are talking about are object reference _vars. You
need to make sure you also do the right thing with servant objects.

[...]
> In WinMainC I have 2 variables for UserImp:
> UserImp* mUser;

This is a pointer to a servant object.

> TCzat::User_var mUser_var;

This is an object reference holder. The _var type automatically
decrements the reference count on the object reference when the _var is
deleted.

> First is for operations, and second is for automatic deletion (after WinMainC::~WinMainC()).
> 
> And in UserImp::destroy():
> mRoomController->removeUser(_this());

This has leaked an object reference. The call to _this() returns an
object reference that you must release. The easiest thing is to assign
it to a _var:

  TCzat::User_var me = _this();
  mRoomController->removeUser(me);

> mRoomController->destroy();
> 
> In the last call (RoomControllerImp::destroy()) I call:
> mPoa->deactivate_object(*mPoa->reference_to_id(_this()));

This has leaked two things!  It leaks the object reference returned by
_this() again, and it leaks the object id returned by reference_to_id().
There's no need for the call to _this(), though. You can use
servant_to_id() instead:

  PortableServant::ObjectId_var oid = mPoa->servant_to_id(this);
  mPoa->deactivate_object(oid);


Now, servant lifecycle. You haven't shown us the place you activate the
object, which is the place the memory management is probably wrong.

When you create a servant object (with new), it has a reference count of
1. When you activate the servant in a POA, the POA increments the
servant's reference count to 2. When you deactivate the object, the
reference count is decremented. When the reference count reaches zero,
the servant is deleted. So, somewhere along the line you need to remove
the reference that the servant had when it was created.

When is best depends on what your creation / activation code looks like.

If, for example, it currently looks like this, using implicit
activation:

  RoomControllerImp* servant = new RoomControllerImp();
  RoomController_var objref = servant->_this();

You can change it to use a servant _var type:

  PortableServer::Servant_var<RoomControllerImp> servant = new RoomControllerImp();
  RoomController_var objref = servant->_this();

When the Servant_var goes out of scope, it calls _remove_ref() on the
servant object. The servant reference count is then 1, and when you call
deactivate_object on the POA, the reference count becomes zero and the
servant is delete.

Duncan.

-- 
 -- Duncan Grisby         --
  -- duncan at grisby.org     --
   -- http://www.grisby.org --





More information about the omniORB-list mailing list