Browse Source

[master] Merged trac4060a (Kea multi-threaded)

Francis Dupont 9 years ago
parent
commit
60ad1417a5

+ 6 - 56
configure.ac

@@ -158,6 +158,7 @@ CXX_VERSION="unknown"
 if test "$SUNCXX" = "yes"; then
 if test "$SUNCXX" = "yes"; then
 CXX_VERSION=`$CXX -V 2> /dev/null | head -1`
 CXX_VERSION=`$CXX -V 2> /dev/null | head -1`
 CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
 CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
+KEA_CXXFLAGS="$KEA_CXXFLAGS -mt"
 MULTITHREADING_FLAG="-mt"
 MULTITHREADING_FLAG="-mt"
 fi
 fi
 
 
@@ -194,6 +195,7 @@ case "$host" in
 	MULTITHREADING_FLAG=-pthread
 	MULTITHREADING_FLAG=-pthread
 	;;
 	;;
 esac
 esac
+KEA_CXXFLAGS="$KEA_CXXFLAGS $MULTITHREADING_FLAG"
 
 
 # Don't use -Werror if configured not to
 # Don't use -Werror if configured not to
 AC_ARG_WITH(werror,
 AC_ARG_WITH(werror,
@@ -1008,7 +1010,7 @@ else
 	done
 	done
 fi
 fi
 
 
-LOG4CPLUS_LIBS="$LOG4CPLUS_LIBS -llog4cplus $MULTITHREADING_FLAG"
+LOG4CPLUS_LIBS="$LOG4CPLUS_LIBS -llog4cplus"
 
 
 AC_SUBST(LOG4CPLUS_LIBS)
 AC_SUBST(LOG4CPLUS_LIBS)
 AC_SUBST(LOG4CPLUS_INCLUDES)
 AC_SUBST(LOG4CPLUS_INCLUDES)
@@ -1016,7 +1018,7 @@ AC_SUBST(LOG4CPLUS_INCLUDES)
 CPPFLAGS_SAVED=$CPPFLAGS
 CPPFLAGS_SAVED=$CPPFLAGS
 CPPFLAGS="$LOG4CPLUS_INCLUDES $CPPFLAGS"
 CPPFLAGS="$LOG4CPLUS_INCLUDES $CPPFLAGS"
 LIBS_SAVED="$LIBS"
 LIBS_SAVED="$LIBS"
-LIBS="$LOG4CPLUS_LIBS $LIBS"
+LIBS="$LOG4CPLUS_LIBS $MULTITHREADING_FLAG $LIBS"
 
 
 AC_CHECK_HEADERS([log4cplus/logger.h],,AC_MSG_ERROR([Missing required header files.]))
 AC_CHECK_HEADERS([log4cplus/logger.h],,AC_MSG_ERROR([Missing required header files.]))
 AC_LINK_IFELSE(
 AC_LINK_IFELSE(
@@ -1072,10 +1074,7 @@ fi
 CPPFLAGS="$CPPFLAGS $CPPFLAGS_BOOST_THREADCONF"
 CPPFLAGS="$CPPFLAGS $CPPFLAGS_BOOST_THREADCONF"
 
 
 # Can be required by gtest, boost and perhaps still asio
 # Can be required by gtest, boost and perhaps still asio
-PTHREAD_LDFLAGS=
-AC_CHECK_LIB(pthread, pthread_create,[ PTHREAD_LDFLAGS=-lpthread ], [])
-AC_SUBST(PTHREAD_LDFLAGS)
-AC_SUBST(MULTITHREADING_FLAG)
+AC_CHECK_LIB(pthread, pthread_create,[ LDFLAGS="$LDFLAGS -lpthread" ], [])
 
 
 #
 #
 # Check availability of gtest, which will be used for unit tests.
 # Check availability of gtest, which will be used for unit tests.
@@ -1116,13 +1115,6 @@ if test "x$enable_gtest" = "xyes" ; then
         GTEST_LDFLAGS="\$(top_builddir)/ext/gtest/libgtest.a"
         GTEST_LDFLAGS="\$(top_builddir)/ext/gtest/libgtest.a"
         DISTCHECK_GTEST_CONFIGURE_FLAG="--with-gtest-source=$GTEST_SOURCE"
         DISTCHECK_GTEST_CONFIGURE_FLAG="--with-gtest-source=$GTEST_SOURCE"
         GTEST_INCLUDES="-I$GTEST_SOURCE -I$GTEST_SOURCE/include"
         GTEST_INCLUDES="-I$GTEST_SOURCE -I$GTEST_SOURCE/include"
-        # See $GTEST_SOURCE/include/gtest/internal/gtest-port.h
-        # about GTEST_HAS_PTHREAD.
-        case "$host" in
-            *-solaris*|*-linux*|*-hpux*)
-                GTEST_LDADD="$GTEST_LDADD $PTHREAD_LDFLAGS"
-                ;;
-        esac
     fi
     fi
 
 
     if test "$gtest_path" != "no" ; then
     if test "$gtest_path" != "no" ; then
@@ -1156,48 +1148,6 @@ if test "x$enable_gtest" = "xyes" ; then
                     GTEST_LDFLAGS="-L$dir/lib"
                     GTEST_LDFLAGS="-L$dir/lib"
                     GTEST_LDADD="-lgtest"
                     GTEST_LDADD="-lgtest"
                     GTEST_FOUND="true"
                     GTEST_FOUND="true"
-                    # There is no gtest-config script on this
-                    # system, which is supposed to inform us
-                    # whether we need pthreads as well (a
-                    # gtest compile-time option). So we still
-                    # need to test that manually.
-                    CPPFLAGS_SAVED="$CPPFLAGS"
-                    CPPFLAGS="$CPPFLAGS $GTEST_INCLUDES"
-                    LDFLAGS_SAVED="$LDFLAGS"
-                    LDFLAGS="$LDFLAGS $GTEST_LDFLAGS"
-                    LIBS_SAVED=$LIBS
-                    LIBS="$LIBS $GTEST_LDADD"
-                    AC_MSG_CHECKING([Checking whether gtest tests need pthreads])
-                    # First try to compile without pthreads
-                    AC_TRY_LINK([
-                        #include <gtest/gtest.h>
-                        ],[
-                            int i = 0;
-                            char* c = NULL;
-                            ::testing::InitGoogleTest(&i, &c);
-                            return (0);
-                        ],
-                        [ AC_MSG_RESULT(no) ],
-                        [
-                            LIBS="$SAVED_LIBS $GTEST_LDADD $PTHREAD_LDFLAGS"
-                            # Now try to compile with pthreads
-                            AC_TRY_LINK([
-                                #include <gtest/gtest.h>
-                                ],[
-                                    int i = 0;
-                                    char* c = NULL;
-                                    ::testing::InitGoogleTest(&i, &c);
-                                    return (0);
-                                ],
-                                [ AC_MSG_RESULT(yes)
-                                  GTEST_LDADD="$GTEST_LDADD $PTHREAD_LDFLAGS"
-                                ],
-                                # Apparently we can't compile it at all
-                                [ AC_MSG_ERROR(unable to compile with gtest) ])
-                    ])
-                    CPPFLAGS=$CPPFLAGS_SAVED
-                    LDFLAGS=$LDFLAGS_SAVED
-                    LIBS=$LIBS_SAVED
                     break
                     break
                 fi
                 fi
             done
             done
@@ -1225,7 +1175,7 @@ CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/ext/coroutine"
 # Doesn't seem to be required?
 # Doesn't seem to be required?
 CPPFLAGS="$CPPFLAGS -DBOOST_ASIO_HEADER_ONLY"
 CPPFLAGS="$CPPFLAGS -DBOOST_ASIO_HEADER_ONLY"
 #
 #
-# Disable threads: Currently we don't use them.
+# Disable threads: they seems to break things on some systems
 CPPFLAGS="$CPPFLAGS -DBOOST_ASIO_DISABLE_THREADS=1"
 CPPFLAGS="$CPPFLAGS -DBOOST_ASIO_DISABLE_THREADS=1"
 
 
 # We tried to stay header only
 # We tried to stay header only

+ 1 - 1
src/lib/hooks/tests/Makefile.am

@@ -1,7 +1,7 @@
 SUBDIRS = .
 SUBDIRS = .
 
 
 AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
 AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 
 AM_CXXFLAGS  = $(KEA_CXXFLAGS)
 AM_CXXFLAGS  = $(KEA_CXXFLAGS)
 # Some versions of GCC warn about some versions of Boost regarding
 # Some versions of GCC warn about some versions of Boost regarding

+ 16 - 4
src/lib/util/process_spawn.cc

@@ -202,9 +202,15 @@ pid_t
 ProcessSpawnImpl::spawn() {
 ProcessSpawnImpl::spawn() {
     // Protect us against SIGCHLD signals
     // Protect us against SIGCHLD signals
     sigset_t sset;
     sigset_t sset;
+    sigset_t osset;
     sigemptyset(&sset);
     sigemptyset(&sset);
     sigaddset(&sset, SIGCHLD);
     sigaddset(&sset, SIGCHLD);
-    sigprocmask(SIG_BLOCK, &sset, 0);
+    pthread_sigmask(SIG_BLOCK, &sset, &osset);
+    if (sigismember(&osset, SIGCHLD)) {
+        isc_throw(ProcessSpawnError,
+                  "spawn() called from a thread where SIGCHLD is blocked");
+    }
+
     // Create the child
     // Create the child
     pid_t pid = fork();
     pid_t pid = fork();
     if (pid < 0) {
     if (pid < 0) {
@@ -212,7 +218,7 @@ ProcessSpawnImpl::spawn() {
 
 
     } else if (pid == 0) {
     } else if (pid == 0) {
         // We're in the child process.
         // We're in the child process.
-        sigprocmask(SIG_UNBLOCK, &sset, 0);
+        sigprocmask(SIG_SETMASK, &osset, 0);
         // Run the executable.
         // Run the executable.
         if (execvp(executable_.c_str(), args_) != 0) {
         if (execvp(executable_.c_str(), args_) != 0) {
             // We may end up here if the execvp failed, e.g. as a result
             // We may end up here if the execvp failed, e.g. as a result
@@ -224,8 +230,14 @@ ProcessSpawnImpl::spawn() {
     }
     }
 
 
     // We're in the parent process.
     // We're in the parent process.
-    process_state_.insert(std::pair<pid_t, ProcessState>(pid, ProcessState()));
-    sigprocmask(SIG_UNBLOCK, &sset, 0);
+    try {
+        process_state_.insert(
+            std::pair<pid_t, ProcessState>(pid, ProcessState()));
+    } catch(...) {
+        pthread_sigmask(SIG_SETMASK, &osset, 0);
+        throw;
+    }
+    pthread_sigmask(SIG_SETMASK, &osset, 0);
     return (pid);
     return (pid);
 }
 }
 
 

+ 1 - 1
src/lib/util/signal_set.cc

@@ -270,7 +270,7 @@ SignalSet::maskSignals(const int mask) const {
          it != registered_signals_->end(); ++it) {
          it != registered_signals_->end(); ++it) {
         sigaddset(&new_set, *it);
         sigaddset(&new_set, *it);
     }
     }
-    sigprocmask(mask, &new_set, 0);
+    pthread_sigmask(mask, &new_set, 0);
 }
 }
 
 
 void
 void

+ 1 - 0
src/lib/util/signal_set.h

@@ -21,6 +21,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <set>
 #include <set>
 #include <list>
 #include <list>
+#include <pthread.h>
 #include <signal.h>
 #include <signal.h>
 
 
 namespace isc {
 namespace isc {

+ 1 - 2
src/lib/util/threads/Makefile.am

@@ -2,12 +2,11 @@ SUBDIRS = . tests
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 
 lib_LTLIBRARIES = libkea-threads.la
 lib_LTLIBRARIES = libkea-threads.la
 libkea_threads_la_SOURCES  = sync.h sync.cc
 libkea_threads_la_SOURCES  = sync.h sync.cc
 libkea_threads_la_SOURCES += thread.h thread.cc
 libkea_threads_la_SOURCES += thread.h thread.cc
 libkea_threads_la_LIBADD  = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
 libkea_threads_la_LIBADD  = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
-libkea_threads_la_LIBADD += $(PTHREAD_LDFLAGS)
 
 
 CLEANFILES = *.gcno *.gcda
 CLEANFILES = *.gcno *.gcda

+ 2 - 2
src/lib/util/threads/tests/Makefile.am

@@ -1,7 +1,7 @@
 SUBDIRS = .
 SUBDIRS = .
 
 
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
+AM_CPPFLAGS += $(BOOST_INCLUDES)
 # XXX: we'll pollute the top builddir for creating a temporary test file
 # XXX: we'll pollute the top builddir for creating a temporary test file
 # # used to bind a UNIX domain socket so we can minimize the risk of exceeding
 # # used to bind a UNIX domain socket so we can minimize the risk of exceeding
 # # the limit of file name path size.
 # # the limit of file name path size.
@@ -26,7 +26,7 @@ run_unittests_SOURCES += lock_unittest.cc
 run_unittests_SOURCES += condvar_unittest.cc
 run_unittests_SOURCES += condvar_unittest.cc
 
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 
 
 run_unittests_LDADD = $(top_builddir)/src/lib/util/threads/libkea-threads.la
 run_unittests_LDADD = $(top_builddir)/src/lib/util/threads/libkea-threads.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la