[omniORB] Proper way for orderly server process shutdown?

Sai-Lai Lo S.Lo@uk.research.att.com
09 Jul 1999 16:50:29 +0100


>>>>> Wil Evers writes:

> While it certainly seems plausible that glibc-2.0 has threading problems,
> I'm afraid I'm still having some trouble using glibc-2.1.  I tried the
> program below on a RedHat 6.0 system; here's the shell output:

> wie@linus: ~/work/tmp2$ make
> omniidl2 Root.idl
> g++ -D_REENTRANT -O2 -c client.cc
> g++ -D_REENTRANT -O2 -c RootSK.cc
> g++ -O2 -o client client.o RootSK.o -lomniORB2 -lomniGK_stub -lomnithread
> -lpthread
> g++ -D_REENTRANT -O2 -c server.cc
> g++ -O2 -o server server.o RootSK.o -lomniORB2 -lomniGK_stub -lomnithread
> -lpthread
> wie@linus: ~/work/tmp2$ ./server
> RootImpl::shutdown()
> disposing rootImpl...
> destroying BOA...
> returning...
> RootImpl::~RootImpl()
> Aborted
> wie@linus: ~/work/tmp2$ ./server
> RootImpl::shutdown()
> disposing rootImpl...
> destroying BOA...
> returning...
> wie@linus: ~/work/tmp2$

> In the first run after the build, the program attempts to destroy the
> implementation object after the BOA has been destroyed, and possibly even
> after main() has returned, leading to an abort.  In the second run, the
> timings are a bit different, and the program doesn't even get around to
> destroying the implementation object.  It looks as though the dispatching
> thread is still running and holding on to the implementation object, even
> after the BOA is destroyed.  Uncommenting the sleep() call in the program
> below helps, but obviously, that's an ugly hack.  So I guess my question
> is: does omniORB provide a way to be sure that no other running threads are
> still trying to manipulate objects, so the program can safely exit from its
> main thread?


Firstly, there is a reference count guarding each implementation
object. When the dtor of the object is called indirectly by _dispose, it is
an invariant that the reference count is zero. The reference count is
incremented every time a server thread has dispatched a call to the object.
I doubt it is a race condition in the implementation object that is causing
a SEGV.

However, after reviewing the code again, I do have to say it is
non-deterministic whether a server thread is still running when the main
thread returns from BOA::destroy(). What BOA::destroy() (or impl_shutdown) 
does is to shutdown all incoming socket. The server threads per connection
should notice the socket state and exit themselves. However, this may
happen before or after impl_destory() has returned, depending on the
behaviour of the underlying thread system.

Having said that, I'm not sure this is the cause of the SEGV you are
seeing. I run my test program with -ORBtraceLevel 20, and I deliberately
put the _dispose() calls after BOA::destroy() (this is not the correct
usage but the implementation allows it). Sometime you see the server
thread exits (message "tcpSocketMT Worker thread: exits.") before the main
thread terminates, some time you don't. But either way, the program does
not crash. I cannot explain this at this stage.

Sai-Lai


-- 
Sai-Lai Lo                                   S.Lo@uk.research.att.com
AT&T Laboratories Cambridge           WWW:   http://www.uk.research.att.com 
24a Trumpington Street                Tel:   +44 1223 343000
Cambridge CB2 1QA                     Fax:   +44 1223 313542
ENGLAND