[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
> >
> >