[omniORB] deleting active servants
Pánczél Levente
Levente.Panczel at compuworx.hu
Fri Dec 19 11:23:14 GMT 2003
Hi Kendall!
Your idea is pretty good, and it brings me a step further, but I don't think it will work. I really can derive a mixin from ServantBase (what you calle DynamicLoadServantBase), and it can do the tasks described in my last letter just fine. The only problem is, that DynamicLoadServantBase is intended to be a base class for any of my servants (ie. TerminalObject, compiled into TermObj.so) thus I have to link TerminalObject.o against DynamicLoadServantBase.o to compile TermObj.so
"mixin should not be part of any shared object" --> I think this unavoidable, since all servants (located in shared objects) would derive from this mixin.
I really don't have any other idea now than to start diging in POA code... :(
Cheers
Levente, Panczel
-----Original Message-----
From: baileyk at schneider.com [mailto:baileyk at schneider.com]
Sent: Wed 2003-12-17 18:26
To: Pánczél Levente
Cc: OmniORB support
Subject: RE: [omniORB] deleting active servants
I believe the safe thing to do would be to write your own mixin class to
replace RefCountServantBase. Your mixin should not be part of any shared
object that is to be unloaded. That would make it safe to call dlclose()
in the _remove_ref() implementation after the destructor is called. As
long as there is no use of the implicit 'this' variable after the
destructor is called it should be OK. Your mixin can call additional
virtual methods on your servant classes if needed to determine the
necessary info for dlclose().
Here's some off-the-cuff pseudo code (synchronization of ref-counts is not
shown)
class DynamicLoadServantBase : public virtual ServantBase {
private:
int ref_count;
public:
virtual void* so_handle() const = 0;
virtual int so_add_ref( int chg ) = 0;
virtual void _remove_ref() {
void* handle = 0;
--ref_count;
if( ref_count == 0 )
{
if( so_add_ref(-1) == 0 )
{
handle = so_handle();
}
delete *this;
}
if( handle )
dlclose( handle );
}
...
}
I'm assuming each servant in a shared object will know the shared object
handle and how to change/query the shared object reference count.
Obviously there need to be more synchronization here. The point is that
your mixin takes on all the responsibility of the standard mixin plus the
detection of unused shared objects.
Kendall
Pánczél Levente
<Levente.Panczel at compuworx.hu To: "Duncan Grisby" <duncan at grisby.org>, "OmniORB support"
> <omniorb-list at omniorb-support.com>
Sent by: cc:
omniorb-list-bounces at omniorb- Fax to:
support.com Subject: RE: [omniORB] deleting active servants
12/17/2003 10:40 AM
Hi!
If I get it right, you suggest that I override _remove_ref(). I could
really do that. Suppose I override _remove_ref() to call dlclose() on the
shared object file's handle if it notices that the object being currently
deallocated is the last instance. This way I would end up in a_remove_ref()
calling dlclose() as its last command. As I see, the call to dlclose()
detaches the file's memory image from the process' address space, causing
the next statement after dlclose() to segfault. The mentioned "next
statement" exists, 'cos the } closing the _remove_ref() definition
generates an ASM RET, which will be deallocated after a call to dlclose().
The best solution would be if POA had a hook, _through_ wich the
_remove_ref() or anything like it would be called.
for example if in the POA's code every
object->_remove_ref()
would be changed to a call like
ReferenceRemoverHook(object);
where ReferenceRemoverHook would be a function pointer in the POA,
initialized to a function only performing the former call to _remove_ref().
Isn't there a mechanism like this?
'Cos I'm sure, if the answer is no, then the object-destruction-triggered
closing of shared objects (DLLs) on concurrent systems involves a large
amount of synchronization.
Cheers
Panczel, Levente
More information about the omniORB-list
mailing list