OpenDNSSEC-signer 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-ia64-j6OroR/opendnssec-1.2.1.dfsg/signer/src/scheduler/locks.c

Go to the documentation of this file.
00001 /*
00002  * $Id: locks.c 4294 2011-01-13 19:58:29Z jakob $
00003  *
00004  * Copyright (c) 2009 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "config.h"
00035 #include "scheduler/locks.h"
00036 #include "util/log.h"
00037 
00038 #include <errno.h>
00039 #include <signal.h> /* sigfillset(), sigprocmask() */
00040 #include <string.h> /* strerror() */
00041 #ifdef HAVE_SYS_TIME_H
00042 #include <sys/time.h> /* gettimeofday() */
00043 #endif
00044 #ifdef HAVE_TIME_H
00045 #include <time.h> /* gettimeofday() */
00046 #endif
00047 
00048 #if !defined(HAVE_PTHREAD)
00049 #include <sys/wait.h> /* waitpid() */
00050 #include <sys/types.h> /* getpid(), waitpid() */
00051 #include <unistd.h> /* fork(), getpid() */
00052 
00053 
00062 void
00063 se_thr_fork_create(se_thread_type* thr, void* (*func)(void*), void* arg)
00064 {
00065     pid_t pid = fork();
00066 
00067     switch (pid) {
00068         default: /* main */
00069                         *thr = (se_thread_type)pid;
00070                         return;
00071                 case 0: /* child */
00072                         *thr = (se_thread_type)getpid();
00073                         (void)(*func)(arg);
00074                         exit(0);
00075                 case -1: /* error */
00076                         se_fatal_exit("unable to fork thread: %s", strerror(errno));
00077         }
00078 }
00079 
00080 
00086 void se_thr_fork_wait(se_thread_type thread)
00087 {
00088     int status = 0;
00089 
00090         if (waitpid((pid_t)thread, &status, 0) == -1)
00091                 se_log_error("waitpid(%d): %s", (int)thread, strerror(errno));
00092         if (status != 0)
00093                 se_log_warning("process %d abnormal exit with status %d",
00094                         (int)thread, status);
00095 }
00096 
00097 #else /* defined(HAVE_PTHREAD) */
00098 
00099 
00100 int
00101 se_thread_wait(cond_basic_type* cond, lock_basic_type* lock, time_t wait)
00102 {
00103     struct timespec ts;
00104     int ret = 0;
00105 
00106     /* If timeshift is enabled, we don't care about threads. No need
00107      & to take the timeshift into account here */
00108 
00109 #ifndef HAVE_CLOCK_GETTIME
00110     struct timeval tv;
00111     if (gettimeofday(&tv, NULL) != 0) {
00112         se_log_error("gettimeofday() error: %s", strerror(errno));
00113         return 1;
00114     }
00115     ts.tv_sec = tv.tv_sec;
00116     ts.tv_nsec = (tv.tv_usec/1000);
00117 #else /* HAVE_CLOCK_GETTIME */
00118     if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
00119         se_log_error("clock_gettime() error: %s", strerror(errno));
00120         return 1;
00121     }
00122 #endif /* !HAVE_CLOCK_GETTIME */
00123 
00124     if (wait > 0) {
00125         ts.tv_sec = ts.tv_sec + wait;
00126         ret = pthread_cond_timedwait(cond, lock, &ts);
00127     } else {
00128         ret = pthread_cond_wait(cond, lock);
00129     }
00130 
00131     if (ret == ETIMEDOUT) {
00132         return 0;
00133     }
00134     return ret;
00135 }
00136 
00137 #endif /* defined(HAVE_PTHREAD) */
00138 
00139 
00140 void
00141 se_thread_blocksigs(void)
00142 {
00143     int err = 0;
00144     sigset_t sigset;
00145     sigfillset(&sigset);
00146 
00147 #ifndef HAVE_PTHREAD
00148     if((err=pthread_sigmask(SIG_SETMASK, &sigset, NULL)))
00149         se_fatal_exit("pthread_sigmask: %s", strerror(err));
00150 #else /* !HAVE_PTHREAD */
00151     /* have nothing, do single process signal mask */
00152     if((err=sigprocmask(SIG_SETMASK, &sigset, NULL)))
00153         se_fatal_exit("sigprocmask: %s", strerror(errno));
00154 #endif /* HAVE_PTHREAD */
00155 }