[omniORB] RE: Catching SIGTERM/SIGHUP using omniORB v3.0
Huw Rogers
count0@building2.co.jp
Tue, 25 Sep 2001 01:55:04 +0900
This should help (I checked that it compiles, and it is
derived from working code I am using):
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
extern "C" {
extern sem_t signal_sem;
extern sem_t hup_sem;
extern sem_t finalize_sem;
extern void *handler_(void *);
extern void handler(int);
};
sem_t signal_sem;
sem_t hup_sem;
sem_t finalize_sem;
volatile CORBA::ORB_ptr the_orb;
void *handler_(void *_)
{
for (;;) {
sem_wait(&signal_sem);
if (!sem_trywait(&hup_sem)) {
// do whatever you need to do here on SIGHUP (reconfigure, etc.)
}
if (!sem_trywait(&finalize_sem)) {
// do whatever you need to do here on SIGINT/SIGTERM
if (the_orb) the_orb->shutdown(!0); // causes the_orb->run() to
return
return(0); // complete this thread
}
}
}
void handler(int s) // the signal handler
{
if (s == SIGHUP)
sem_post(&hup_sem);
else
sem_post(&finalize_sem);
sem_post(&signal_sem);
}
int main(int argc, char **argv)
{
// ...
sem_init(&signal_sem, 0, 0);
sem_init(&hup_sem, 0, 0);
sem_init(&finalize_sem, 0, 0);
{
thread_t _;
pthread_create(&_, 0, handler_, 0);
}
{
struct sigaction action;
action.sa_handler = handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGHUP, &action, 0);
sigaction(SIGINT, &action, 0);
sigaction(SIGTERM, &action, 0);
}
// ...
the_orb = CORBA::ORB_init(argc, argv, "");
// ...
the_orb->run();
// run() only returns once shutdown() has completed
the_orb->destroy();
return(0);
}
Mark Johnson wrote:
>
> Well can anyone give a "best practices" or some common (complete?) example
> of how to do this? I mean how many ways can you alert your application that
> a SIGTERM has just been recieved?
>
> This is what I'm doing (which is wrong).
>
> void HandleSIGTERM(int sig)
> {
> signal( sig, HandleSIGTERM ); // should change this to 'sigaction'
> ThreadInfo::setStopping();
> SLEEP( 5 ); // KLUDGE!
> exit( 0 ); // FIX THIS: don't know how/where to stop CORBA::run() yet...
> }
>
> and all my threads have this as a main loop:
>
> void MyCorbaThread::run( void * arg )
> {
> while( ThreadInfo::isStopping() == false )
> {
> // ... do stuff...
> }
> }
>
> So in the archives I have found the following, which is pretty informative:
> http://www.uk.research.att.com/omniORB/archives/2001-01/0190.html
>
> Would anyone else be interested in having an example of how to handle
> signals as a part of the OminORB distribution. I could maybe contribute,
> but I'm not sure that I am qualified. Right now, I'm very much a newbie.
>
> > -----Original Message-----
> > From: Huw Rogers [mailto:count0@building2.co.jp]
> > Sent: Tuesday, September 18, 2001 4:12 AM
> > To: Mark Johnson
> > Cc: 'OmniOrb Mailing List (E-mail)'
> > Subject: Re: [omniORB] RE: Catching SIGTERM/SIGHUP using omniORB v3.0
> >
> >
> > Mixing signal handling, threads and ORBs
> > is hazardous. In particular, a signal handler
> > cannot safely acquire a mutex or create
> > another thread. You can cause core dumps and
> > deadlocks if you try, particularly on SMP systems.
> > This means you can't call any ORB library
> > functions either directly or indirectly from
> > within signal handlers.
> >
> > In fact, the only portable and safe thing to do
> > is have a separate cleanup thread waiting on
> > a semaphore and call sem_post() in the signal
> > handler, which is one of the very few pthreads
> > functions that is portably Async-signal safe
> > (pthread_cond_broadcast and/or pthread_cond_signal
> > are not).
> >
> > Also, use sigaction() to register handlers, to
> > avoid the usual ambiguities of signal().
> >
> > Mixing Unix signal handlers and shutdown of
> > multithreaded libraries is an FAQ - it should be
> > definitively described somewhere, but isn't
> > AFAIK.
> >
> > -Huw
> >
> >