Skip to content

Commit

Permalink
signal handling improvment
Browse files Browse the repository at this point in the history
  • Loading branch information
rishithaminol committed Mar 22, 2018
1 parent f4bc634 commit 58eb315
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 84 deletions.
2 changes: 1 addition & 1 deletion httpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ int __cb_main_thread(MYSQL *db, int port_num)
sockfd = accept(global_data_handle.httpd_sockfd, (struct sockaddr *)&client_sockaddr, &clilen);
if (sockfd == -1) {
CM_ERROR("Connection accept error\n");
continue;
break;
} else {
DEBUG_MSG("Client accepted connection\n");
cb_arg = (struct __cb_args *)malloc(sizeof(struct __cb_args));
Expand Down
87 changes: 7 additions & 80 deletions signal_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,90 +4,17 @@
#include <unistd.h> // alarm()

#include "signal_handler.h"
#include "cm_debug.h"
#include "cmarketcap.h"

void handle_signal(int signal)
void handle_SIGINT(int signal)
{
const char *signal_name;
sigset_t pending;

// Find out which signal we're handling
switch (signal) {
case SIGHUP:
signal_name = "SIGHUP";
break;
case SIGUSR1:
signal_name = "SIGUSR1";
break;
case SIGINT:
printf("Caught SIGINT, exiting now\n");
close(global_data_handle.httpd_sockfd);
exit(0);
default:
fprintf(stderr, "Caught wrong signal: %d\n", signal);
return;
}

/*
* Please note that printf et al. are NOT safe to use in signal handlers.
* Look for async safe functions.
*/
printf("Caught %s, sleeping for ~3 seconds\n"
"Try sending another SIGHUP / SIGINT / SIGALRM "
"(or more) meanwhile\n", signal_name);

/*
* Indeed, all signals are blocked during this handler
* But, at least on OSX, if you send 2 other SIGHUP,
* only one will be delivered: signals are not queued
* However, if you send HUP, INT, HUP,
* you'll see that both INT and HUP are queued
* Even more, on my system, HUP has priority over INT
*/
do_sleep(3);
printf("Done sleeping for %s\n", signal_name);

// So what did you send me while I was asleep?
sigpending(&pending);
if (sigismember(&pending, SIGHUP)) {
printf("A SIGHUP is waiting\n");
}
if (sigismember(&pending, SIGUSR1)) {
printf("A SIGUSR1 is waiting\n");
}

printf("Done handling %s\n\n", signal_name);
} /* handle_signal */

void handle_sigalrm(int signal)
{
if (signal != SIGALRM) {
fprintf(stderr, "Caught wrong signal: %d\n", signal);
}

printf("Got sigalrm, do_sleep() will end\n");
printf("Caught SIGINT, exiting now\n");
close(global_data_handle.httpd_sockfd);
}

void do_sleep(int seconds)
void init_sighandlers()
{
struct sigaction sa;
sigset_t mask;

sa.sa_handler = &handle_sigalrm; // Intercept and ignore SIGALRM
sa.sa_flags = SA_RESETHAND; // Remove the handler after first signal
sigfillset(&sa.sa_mask);
sigaction(SIGALRM, &sa, NULL);

// Get the current signal mask
sigprocmask(0, NULL, &mask);

// Unblock SIGALRM
sigdelset(&mask, SIGALRM);

// Wait with this mask
alarm(seconds);
sigsuspend(&mask);

printf("sigsuspend() returned\n");
if (signal(SIGINT, handle_SIGINT) == SIG_ERR)
CM_ERROR("can't catch SIGINT\n");
}

5 changes: 2 additions & 3 deletions signal_handler.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#ifndef SIGNAL_HANDLER_H_
#define SIGNAL_HANDLER_H_

extern void handle_signal(int signal);
extern void handle_sigalrm(int signal);
extern void do_sleep(int seconds);
extern void handle_SIGINT(int signal);
extern void init_sighandlers();

#endif

0 comments on commit 58eb315

Please sign in to comment.