Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Make zctx_destroy restore original sighandler #107

merged 1 commit into from

2 participants

Felipe Cruz Pieter Hintjens
Felipe Cruz

No description provided.

Pieter Hintjens

The problem with this change is that it breaks the case where an application does multiple zctx_new() and zctx_destroy() calls.

Also, the management of interrupts should perhaps go into a zsys now, it's not portable and messier than I'd like in zctx.

The problem is to allow CZMQ's interrupt handling to co-exist with external interrupt handling.

I'd suggest two new API calls,

  • zsys_handler_set - sets interrupt handler, NULL means application provides one already
  • zsys_handler_reset - resets interrupt handler that was saved in zctx_new(), if it wasn't null

Note that zctx_new() then needs a first time flag to call zsys_handler_set() only once.


I've missed that case.. Move this to zsys looks good! I'll fix that soon!

Pieter Hintjens hintjens merged commit 8a7301f into from
Pieter Hintjens

I'm merging this and will refactor it via zsys like I suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 3, 2013
  1. Felipe Cruz
This page is out of date. Refresh to see the latest.
Showing with 32 additions and 2 deletions.
  1. +32 −2 src/zctx.c
34 src/zctx.c
@@ -64,6 +64,7 @@ struct _zctx_t {
bool main; // True if we're the main thread
int iothreads; // Number of IO threads, default 1
int linger; // Linger timeout, default 0
+ struct sigaction oacts[2]; // Current sigaction values
@@ -108,8 +109,8 @@ zctx_new (void)
action.sa_handler = s_signal_handler;
action.sa_flags = 0;
sigemptyset (&action.sa_mask);
- sigaction (SIGINT, &action, NULL);
- sigaction (SIGTERM, &action, NULL);
+ sigaction (SIGINT, &action, &self->oacts[0]);
+ sigaction (SIGTERM, &action, &self->oacts[1]);
return self;
@@ -130,6 +131,10 @@ zctx_destroy (zctx_t **self_p)
zlist_destroy (&self->sockets);
if (self->main && self->context)
zmq_term (self->context);
+#if defined (__UNIX__)
+ sigaction (SIGINT, &self->oacts[0], NULL);
+ sigaction (SIGTERM, &self->oacts[1], NULL);
free (self);
*self_p = NULL;
@@ -292,8 +297,33 @@ zctx_test (bool verbose)
zsocket_connect (s6, "tcp://");
assert (zctx_underlying (ctx));
+#if defined (__UNIX__)
+ struct sigaction action;
+ sigaction (SIGINT, NULL, &action);
+ assert (action.sa_handler == s_signal_handler);
+ sigaction (SIGTERM, NULL, &action);
+ assert (action.sa_handler == s_signal_handler);
// Everything should be cleanly closed now
zctx_destroy (&ctx);
+ sigaction (SIGINT, NULL, &action);
+ sigaction (SIGTERM, NULL, &action);
+ assert (action.sa_handler != s_signal_handler);
+ assert (action.sa_handler != s_signal_handler);
+ // Check if no signal handler is installed if zctx_interrupted
+ zctx_interrupted = 1;
+ bzero(&action, sizeof(struct sigaction));
+ ctx = zctx_new ();
+ sigaction (SIGINT, NULL, &action);
+ assert (action.sa_handler != s_signal_handler);
+ sigaction (SIGTERM, NULL, &action);
+ assert (action.sa_handler != s_signal_handler);
+ zctx_destroy (&ctx);
// @end
printf ("OK\n");
Something went wrong with that request. Please try again.