Skip to content

Instantly share code, notes, and snippets.

@davisford
Created November 8, 2012 23:06
Show Gist options
  • Save davisford/4042467 to your computer and use it in GitHub Desktop.
Save davisford/4042467 to your computer and use it in GitHub Desktop.
signals
/**
* toggle flag that controls while loop in main()
*/
static void s_signal_handler (int sig) {
s_interrupted = 1;
}
/**
* trap on SIGINT | SIGTERM
*/
static void setup_signal_handler (void) {
struct sigaction action;
action.sa_handler = s_signal_handler;
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
}
/**
* main creates background daemon, starts zthread and zloop reactor
*/
int main (int argc, char **argv) {
setup_signal_handler();
// run as daemon
daemonize();
// now running as forked child process...
zctx_t *ctx = zctx_new();
if (ctx == NULL) { /* error handling */ }
void *pipe = zthread_fork (ctx, do_work, NULL);
if (pipe == NULL) { /* error handling */ }
while (true) {
if (s_interrupted) {
syslog(LOG_INFO, "interrupted");
break;
}
syslog(LOG_INFO, "waiting for message from child...");
char* msg = zstr_recv(pipe);
syslog(LOG_INFO, "received: %s", msg);
if (strcmp("exit", msg) == 0) {
free(msg); _do_exit();
}
free(msg);
}
syslog(LOG_ALERT, "should not get here");
_do_exit();
}
/**
* cleans up all resources
*/
void _do_exit() {
// cleanup code
}
/**
* spawn child process, etc.
*/
static void daemonize() {
pid_t pid, sid, parent;
// fork off parent
pid = fork();
if (pid < 0) { /* error handling */ }
if (pid > 0) {
// exit parent process
exit(EXIT_SUCCESS);
}
umask(0);
sid = setsid();
if (sid < 0) { /* error handling */ }
if ( (chdir("/")) < 0) { /* error handling */ }
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
}
/**
* main worker attached thread
*/
void do_work(void *args, zctx_t *ctx, void *pipe) {
zloop_t *reactor = zloop_new();
if (reactor == NULL) { /* error handling */ }
int ret = zloop_timer(reactor, period, 0, do_periodic_work, pipe);
if (ret != 0) { /* error handling */ }
client = zsocket_new(ctx, ZMQ_REQ);
if (client = NULL) { /* error handling */ }
ret = zsocket_connect(client, url);
if (ret != 0) { /* error handling */ }
// shouldn't return until handler returns -1 or SIGINT, etc.
ret = zloop_start(&reactor);
// message parent to exit
zstr_send(pipe, "exit");
zloop_destroy(&reactor);
zsocket_destroy(ctx, client);
}
/**
* executes on zloop timer
*/
int do_periodic_work(zloop_t *loop, zmq_pollitem_t *item, void *pipe) {
// does work, return -1 to terminate
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment