static cache_item_t *cache_queue_tail = NULL;
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
+static sigset_t signal_set;
static int config_write_interval = 300;
static int config_write_jitter = 0;
static int config_flush_interval = 3600;
static void sig_common (const char *sig) /* {{{ */
{
RRDD_LOG(LOG_NOTICE, "caught SIG%s", sig);
+
+ int status = pthread_mutex_lock(&cache_lock);
+
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Lock failed.", status);
+ abort();
+ }
+
if (state == RUNNING) {
state = FLUSHING;
}
pthread_cond_broadcast(&flush_cond);
+ status = pthread_mutex_unlock(&cache_lock);
+
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Unlock failed.", status);
+ abort();
+ }
+
pthread_cond_broadcast(&queue_cond);
} /* }}} void sig_common */
-static void sig_int_handler (int UNUSED(s)) /* {{{ */
+static void* signal_receiver (void UNUSED(*args))
{
- sig_common("INT");
-} /* }}} void sig_int_handler */
+ siginfo_t signal_info;
+ int status;
-static void sig_term_handler (int UNUSED(s)) /* {{{ */
-{
- sig_common("TERM");
-} /* }}} void sig_term_handler */
+ while (1)
+ {
+ status = sigwaitinfo(&signal_set, &signal_info);
-static void sig_usr1_handler (int UNUSED(s)) /* {{{ */
-{
- config_flush_at_shutdown = 1;
- sig_common("USR1");
-} /* }}} void sig_usr1_handler */
+ switch(status)
+ {
+ case -1:
+ RRDD_LOG(LOG_ERR, "%s: %s\nerrno: %d", __func__, "Signal wait failed.", errno);
+ abort();
-static void sig_usr2_handler (int UNUSED(s)) /* {{{ */
-{
- config_flush_at_shutdown = 0;
- sig_common("USR2");
-} /* }}} void sig_usr2_handler */
+ case SIGINT:
+ sig_common("INT");
+ break;
+
+ case SIGTERM:
+ sig_common("TERM");
+ break;
+
+ case SIGUSR1:
+ status = pthread_mutex_lock(&cache_lock);
+
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Lock failed.", status);
+ abort();
+ }
+
+ config_flush_at_shutdown = 1;
+ status = pthread_mutex_unlock(&cache_lock);
-static void install_signal_handlers(void) /* {{{ */
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Unlock failed.", status);
+ abort();
+ }
+
+ sig_common("USR1");
+ break;
+
+ case SIGUSR2:
+ status = pthread_mutex_lock(&cache_lock);
+
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Lock failed.", status);
+ abort();
+ }
+
+ config_flush_at_shutdown = 0;
+ status = pthread_mutex_unlock(&cache_lock);
+
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Unlock failed.", status);
+ abort();
+ }
+
+ sig_common("USR2");
+ break;
+
+ default:
+ RRDD_LOG(LOG_NOTICE,
+ "%s: Signal %d was received from process %u.\n",
+ __func__,
+ status,
+ signal_info.si_pid);
+ }
+ }
+
+ return NULL;
+}
+
+static void install_signal_receiver(void)
{
- /* These structures are static, because `sigaction' behaves weird if the are
- * overwritten.. */
- static struct sigaction sa_int;
- static struct sigaction sa_term;
- static struct sigaction sa_pipe;
- static struct sigaction sa_usr1;
- static struct sigaction sa_usr2;
+ pthread_t receiver;
+ int status = sigfillset(&signal_set);
- /* Install signal handlers */
- memset (&sa_int, 0, sizeof (sa_int));
- sa_int.sa_handler = sig_int_handler;
- sigaction (SIGINT, &sa_int, NULL);
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nerrno: %d", "Signal set could not be initialised.", errno);
+ abort();
+ }
+
+ /* Block all signals in the initial thread. */
+ status = pthread_sigmask(SIG_SETMASK, &signal_set, NULL);
- memset (&sa_term, 0, sizeof (sa_term));
- sa_term.sa_handler = sig_term_handler;
- sigaction (SIGTERM, &sa_term, NULL);
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "Signal mask could not be set.", status);
+ abort();
+ }
- memset (&sa_pipe, 0, sizeof (sa_pipe));
- sa_pipe.sa_handler = SIG_IGN;
- sigaction (SIGPIPE, &sa_pipe, NULL);
+ status = pthread_create(&receiver, NULL, signal_receiver, NULL);
- memset (&sa_pipe, 0, sizeof (sa_usr1));
- sa_usr1.sa_handler = sig_usr1_handler;
- sigaction (SIGUSR1, &sa_usr1, NULL);
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "A thread could not be created.", status);
+ abort();
+ }
- memset (&sa_usr2, 0, sizeof (sa_usr2));
- sa_usr2.sa_handler = sig_usr2_handler;
- sigaction (SIGUSR2, &sa_usr2, NULL);
+ status = pthread_detach(receiver);
-} /* }}} void install_signal_handlers */
+ if (status)
+ {
+ RRDD_LOG(LOG_ERR, "%s\nstatus: %d", "A thread could not be detached.", status);
+ abort();
+ }
+}
static int open_pidfile(char *action, int oflag) /* {{{ */
{
goto error;
}
- install_signal_handlers();
-
openlog ("rrdcached", LOG_PID, LOG_DAEMON);
RRDD_LOG(LOG_INFO, "starting up");
+ install_signal_receiver();
cache_tree = g_tree_new_full ((GCompareDataFunc) strcmp, NULL, NULL,
(GDestroyNotify) free_cache_item);