Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to terminate a socket server gracefully?

Status
Not open for further replies.

lichtjiang

Programmer
Feb 26, 2007
39
US
I have a server using unix domain socket. It works in a standard way: listening for requests and accepting each of them by running a separater thread for it:

while(true){
int clientsocket;


clientsocket=accept(serversocket, NULL, NULL);

ClientHandler * ch = new ClientHandler(someparameters, clientsocket);
ch->start();
}

So, how to terminate this server gracefully? I think some signal handler can be used for this purpose though I haven't done so and it's ok to do "kill -TERM pid" w/o the signal is handled by the server. But since there is a lot of cleanning work to do for each socket connection, this is not something recommended. Any idea or suggestion? Thanks!
 
Code:
volatile int terminated = 0;

int handler ( int sig ) {
    if ( sig == SIG_TERM ) {
        terminated = 1;
    }
    return 0;
}


while( ! terminated ) {
    int clientsocket;
         
    clientsocket=accept(serversocket, NULL, NULL);

    if ( ! terminated ) {
        ClientHandler * ch = new ClientHandler(someparameters, clientsocket);
        ch->start();
    } else {
        break;
    }
}
All the existing client handler threads should check the same flag as well, in the same way - exit whatever loop they're in, clean up and exit normally.

You might need to look at using select() to guard each socket function. I've had a quick read of accept(), but there is no mention of it returning with EINTR, whereas select does return EINTR.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Thanks a lot!

Several doubts.

- in each client handler, how it is notified of a SIGTERM signal? I guess there should be only one instance of signal handler running and it is as what you coded in above. But how signal handler pass the signal to each running processes and threads in real-time (though a global flag can be set as what you said)? I think by using a flag is enough. But just want to know if there is other elegant ways.

- what do you mean by "... using select() ...". not really follow you. Could you please throw some more light on this?

Thanks!
 
Well you could try manipulating the thread signal mask, if your particular implementation of threads has such a thing.

You might get something more 'elegant', but it seems like a lot of work just so you can quit the application.

Bear in mind that signals live in a world of their own. It's a very different environment in terms of say how signals are queued (if at all), which threads get signal handlers invoked and the range of API calls (not many) you're allowed to call inside a signal handler. Setting a global and returning may seem crude, but it is easy to implement and test.

> Could you please throw some more light on this?
select() is a system call which allows you to monitor multiple descriptors for changes in state - like data becoming available for reading.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top