[omniORB] Proper way for orderly server process shutdown?

Wil_Evers@doosys.com Wil_Evers@doosys.com
Fri, 09 Jul 1999 14:04:12 GMT


Hi Sai-Lai,

You wrote :

> With regard to the the program core dump on linux, I've also seen
> this on machines running glibc-2.0. It happens about once out of
> 20 invocations.  I cannot figure out what is causing this. However
> if you look at where it SEGV under gdb, its always inside the pthread
> library. Since I cannot find any wrong with the shutdown code, I've
> classified this one as a bug in glibc-2.0.

> I've also tested the same program on a Redhat 6.0 machine that comes
> with glibc-2.1. So far I've not seen one core dump. This may be an
> indication that the problem has been fixed in glibc-2.1.

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?

Thanks again,

- Wil

Wil Evers, DOOSYS IT Consultants, Maarssen, Holland



Example program:

#include <iostream.h>
#include <fstream.h>
#include <unistd.h>
#include "Root.hh"

class RootImpl : public virtual _sk_Root {

public :
     RootImpl (CORBA::BOA_ptr boa_) ;

     void shutdown () ;

     virtual ~RootImpl () ;

private :
     CORBA::BOA_ptr boa ;
} ;

RootImpl::RootImpl (CORBA::BOA_ptr boa_) :
     _sk_Root (),
     boa (boa_) {
}

void RootImpl::shutdown () {

     cout << "RootImpl::shutdown()" << endl ;
     boa->impl_shutdown () ;
}

RootImpl::~RootImpl () {

     cout << "RootImpl::~RootImpl()" << endl ;
}

int main (int argc_, char *argv_ []) {

     CORBA::ORB_var orb = CORBA::ORB_init (argc_, argv_, "omniORB2") ;
     CORBA::BOA_var boa = orb->BOA_init (argc_, argv_, "omniORB2_BOA") ;

     RootImpl *rootImpl = new RootImpl (boa) ;
     rootImpl->_obj_is_ready (boa) ;

     {
          Root_var rootProxy = rootImpl->_this () ;
          CORBA::String_var s = orb->object_to_string (rootProxy) ;
          ofstream of ("root.ior") ;
          of << s << endl ;
     }


     boa->impl_is_ready () ;

/*
     cout << "winding down..." << endl ;
     sleep (1) ;
 */

     cout << "disposing rootImpl..." << endl ;
     rootImpl->_dispose () ;

     cout << "destroying BOA..." << endl ;
     boa->destroy () ;

     cout << "returning..." << endl ;
     return 0 ;
}