[omniORB] OmniORB in a COM object

David Hyde davidh@cavendish.co.uk
Tue, 20 Feb 2001 09:02:33 -0000


Claudio,

Thanks for the response.

This was worrying me on two counts.  Firstly, yes the OO programmer in me
was shuddering at the ways that I was having to try to get around this, but
I never let this get to me too much when a solution just has to be found.
Of more concern was the comment in the OmniORB documentation that said
destroy() has to be called, especially when incorporating into an ActiveX
control.  However, I've left the call the destroy() out and things do seem
to be working perfectly satisfactorily.

So I'll let it be for now and see how I get on.

David





________________________________________________________
David Hyde
The Cavendish Organisation Ltd.        
Admiral House                       
St. Leonards Rd				Tel: +44 1753 836600 
Windsor					Fax: +44 1753 855021         
Berkshire SL4 3BL 
United Kingdom

email: davidh@cavendish.co.uk

http://www.cavendish.co.uk/ 

Confidential Information may be in this message. If you are not the
intended
addressee please treat it as confidential, contact us immediately. Thank
you.
______________________________________________________________



-----Original Message-----
From: Claudio Natoli [mailto:claudio.natoli@memetrics.com]
Sent: Tuesday, February 20, 2001 3:39 AM
To: 'David Hyde'; OmniOrb mailing list (E-mail)
Subject: RE: [omniORB] OmniORB in a COM object



Hi David,

I've been secretly hoping that someone else (with better solutions than
we've found) would provide answers to this and your previous post, having
encountered the exact same problem without arriving at a satisfactory
solution.

Since that hasn't happened (as yet?) I'll throw in my 2 cents worth...


> I'm using OmniORB in a COM object.  This object is going to 
> be used in an
> Internet Server application so the dll that contains the 
> control will be
> started once, then multiple instances of the control will be 
> created by IIS.
> I have made the ORB and the root POA global objects in the application
> object that all instances of the control can access.  The 
> first instance of
> the control calls ORB_init() when it processes a command (not in its
> constructor).  What I can't have is the control calling 
> orb->destroy() as
> this would prevent any subsequent instances of the control 
> (in the same dll
> instance) working.  So I have tried putting destroy into the dll's
> ExitInstance() and the main dll application object's 
> destructor, but the
> application hangs in the call to destroy().


My understanding is as follows:

The underlying reason why the application hangs during the destroy() call is
because of the way the Windows kernel serializes calls to the DllMain
routine. Specifically, only 1 thread is ever allowed to attach to/detach
from/etc. a dll at any point in time... the kernel makes any other threads
which attempt to do so wait until the initial call completes.

In your case, the destroy() call causes one or more orb threads to
terminate, and waits for those terminations to complete. As part of their
termination, these threads will detach from any attached dll's. However, you
issue the destroy() call from ExitInstance, which is *itself* called from
DllMain... 

And therein lies the deadlock: The destroy() call won't return until the orb
threads terminate, and they won't terminate until the thread making the
ExitInstance call exits the DllMain routine.


> Can anyone tell me how I should handle this? 

Firstly, if you can place the destroy() call such that it is invoked prior
to the invocation of DllMain/ExitInstance (ie. some Terminate() function
that gets called prior to the DLL being unloaded), then do so. 

However, given that you chose to put the destroy() call in ExitInstance in
the first place, I'm guessing that this is the only logical place that you
have for this call to go. We faced the same situation ourselves some months
ago, and after a great deal of experimentation with alternative "solutions"
and purist soul-searching we came up with the following solution: don't call
orb->destroy().

In our (initial) application and I'm assuming in yours as well, the call to
ExitInstance will only arrive when IIS is itself terminating (so memory
leaks etc. associated with NOT calling destroy() are a bit of a moot point).
The purist in me still feels violated, but in the end we just needed to get
something going, and so the pragmatist won out! In any case, we didn't have
any problems with this approach, though your mileage may vary. [can you
guess how tell how uncomfortable I am recommending this?]


Another possible solution you may not have considered (or may not find
acceptable) is to use an out-of-process server rather than an in-process
DLL. You could simply initialise/terminate the orb from the WinMain
function, though keep in mind that, being OOP, you will cop a performance
hit. 


In addition, Renzo Tomaselli provided another possible solution in a
previous post
(http://www.uk.research.att.com/omniORB/archives/2000-03/0012.html), however
this is unlikely to be of use to you in an IIS application (though others
reading this may find it useful).

Best of luck,
Claudio

PS. All comments/suggestions/flames welcome!