views:

66

answers:

2

I have a simple server that looks something like this:

void *run_thread(void *arg) {
    // Communicate via a blocking socket
}

int main() {
    // Initialization happens here...

    // Main event loop
    while (1) {
        new_client = accept(socket, ...);
        pthread_create(&thread, NULL, &run_thread, *thread_data*);
        pthread_detach(thread);
    }

    // Do cleanup stuff:
    close(socket);
    // Wait for existing threads to finish
    exit(0); 
)

Thus when a SIGINT or SIGTERM is received I need to break out of the main event loop to get to the clean up code. Moreover most likely the master thread is waiting on the accept() call so it's not able to check some other variable to see if it should break;.

Most of the advice I found was along the lines of this: http://devcry.blogspot.com/2009/05/pthreads-and-unix-signals.html (creating a special signal handling thread to catch all the signals and do processing on those). However, it's the processing portion that I can't really wrap my head around: how can I possibly tell the main thread to return from the accept() call and check on an external variable to see if it should break;?

+2  A: 

Usually I am waiting on select(listeninig-socket-here) not on accept(). accept() is usually a method where a program doesn't spend lots of time waiting. And when I wait in select() and the signal SIGTERM is sent to that thread (in your case it is the main thread) I exit from that select and select returns interrupted system call .

skwllsp
Thanks, that worked.
ipartola
A: 

I second skwllsp in his opinion that you should be using select call instead of accept. But, my additional suggestion is that you follow the advice of the blog whose link you have posted and create a seperate signal handling thread and ignore signals in all other threads. Then when the signal is received in the signal handling thread, use pthread_cancel to cancel the other threads. When you use pthread_cancel, if the thread which is being cancelled is in cancellation point (select happens to be one), it will come out and enter into your handler and you can cleanup and exit the thread.

You can find more info on this here, here and here

Jay
Yes, that's what I ended up doing. I also used pthread_cleanup_push and pthread_cleanup_pop. Works like a charm.
ipartola
Good.Actually, the idea and concept of pthread_cancel is brilliant according to me. : )
Jay