]> granicus.if.org Git - icinga2/commitdiff
Fine-grained locks (WIP, Part 8).
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 21 Feb 2013 15:12:50 +0000 (16:12 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 21 Feb 2013 15:12:50 +0000 (16:12 +0100)
13 files changed:
autogen.sh
components/checker/checkercomponent.cpp
configure.ac
lib/base/Makefile.am
lib/base/application.cpp
lib/base/application.h
lib/base/object.h
lib/config/Makefile.am
lib/icinga/Makefile.am
lib/icinga/service-check.cpp
lib/python/Makefile.am
lib/remoting/Makefile.am
libtool-pch.patch [new file with mode: 0644]

index 17b17bdc22d91732009ad1f2faa7dfc8fc885fde..09e9b9f6ef45f3880277e2d4f2d4c975834ba001 100755 (executable)
@@ -186,6 +186,12 @@ do
       automake --add-missing --gnu $am_opt
       echo "Running autoconf ..."
       autoconf
+
+      if ! patch --dry-run -p0 < libtool-pch.patch >/dev/null; then
+        echo "Warning: Libtool patch did not apply cleanly."
+      else
+        patch -p0 < libtool-pch.patch
+      fi
     )
   fi
 done
index f260e94a096c87b57c67b6879bdb0a0d46fa51e8..e9136beb65894531663afca74085befb810c1813 100644 (file)
@@ -63,27 +63,26 @@ void CheckerComponent::CheckThreadProc(void)
                vector<Service::Ptr> services;
                Service::Ptr service;
 
-               {
-                       boost::mutex::scoped_lock lock(m_Mutex);
+               boost::mutex::scoped_lock lock(m_Mutex);
 
-                       typedef nth_index<ServiceSet, 1>::type CheckTimeView;
-                       CheckTimeView& idx = boost::get<1>(m_IdleServices);
+               typedef nth_index<ServiceSet, 1>::type CheckTimeView;
+               CheckTimeView& idx = boost::get<1>(m_IdleServices);
 
-                       while (idx.begin() == idx.end() && !m_Stopped)
-                               m_CV.wait(lock);
+               while (idx.begin() == idx.end() && !m_Stopped)
+                       m_CV.wait(lock);
 
-                       if (m_Stopped)
-                               break;
+               if (m_Stopped)
+                       break;
 
-                       CheckTimeView::iterator it = idx.begin();
-                       service = it->lock();
+               CheckTimeView::iterator it = idx.begin();
+               service = it->lock();
 
-                       if (!service) {
-                               idx.erase(it);
-                               continue;
-                       }
+               if (!service) {
+                       idx.erase(it);
+                       continue;
                }
 
+               ObjectLock olock(service); /* also required for the key extractor. */
                double wait;
 
                {
@@ -92,23 +91,20 @@ void CheckerComponent::CheckThreadProc(void)
                }
 
                if (wait > 0) {
+                       /* Release the object lock. */
+                       olock.Unlock();
+
                        /* Make sure the service we just examined can be destroyed while we're waiting. */
                        service.reset();
 
                        /* Wait for the next check. */
-                       boost::mutex::scoped_lock lock(m_Mutex);
                        if (!m_Stopped)
                                m_CV.timed_wait(lock, boost::posix_time::milliseconds(wait * 1000));
 
                        continue;
                }
 
-               {
-                       boost::mutex::scoped_lock lock(m_Mutex);
-                       m_IdleServices.erase(service);
-               }
-
-               ObjectLock olock(service); /* also required for the key extractor */
+               m_IdleServices.erase(service);
 
                /* reschedule the service if checks are currently disabled
                 * for it and this is not a forced check */
@@ -118,35 +114,27 @@ void CheckerComponent::CheckThreadProc(void)
 
                                service->UpdateNextCheck();
 
-                               {
-                                       boost::mutex::scoped_lock lock(m_Mutex);
-
-                                       typedef nth_index<ServiceSet, 1>::type CheckTimeView;
-                                       CheckTimeView& idx = boost::get<1>(m_IdleServices);
+                               typedef nth_index<ServiceSet, 1>::type CheckTimeView;
+                               CheckTimeView& idx = boost::get<1>(m_IdleServices);
 
-                                       idx.insert(service);
-                               }
+                               idx.insert(service);
 
                                continue;
                        }
                }
 
                service->SetForceNextCheck(false);
-
                service->SetFirstCheck(false);
 
                Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'");
 
-               {
-                       boost::mutex::scoped_lock lock(m_Mutex);
-                       m_IdleServices.erase(service);
-                       m_PendingServices.insert(service);
-               }
+               m_IdleServices.erase(service);
+               m_PendingServices.insert(service);
 
                double rwait = service->GetNextCheck() - Utility::GetTime();
 
-               if (abs(rwait - wait) > 5)
-                       Logger::Write(LogWarning, "checker", "Check delayed: " + Convert::ToString(-rwait) + ",planned wait: " + Convert::ToString(-wait));
+               if (rwait < -5)
+                       Logger::Write(LogWarning, "checker", "Check delayed: " + Convert::ToString(-rwait));
 
                try {
                        service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, this, service));
@@ -156,23 +144,21 @@ void CheckerComponent::CheckThreadProc(void)
        }
 }
 
+
 void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service)
 {
+       boost::mutex::scoped_lock lock(m_Mutex);
        ObjectLock olock(service); /* required for the key extractor */
 
-       {
-               boost::mutex::scoped_lock lock(m_Mutex);
-
-               /* remove the service from the list of pending services; if it's not in the
-                * list this was a manual (i.e. forced) check and we must not re-add the
-                * service to the services list because it's already there. */
-               CheckerComponent::ServiceSet::iterator it;
-               it = m_PendingServices.find(service);
-               if (it != m_PendingServices.end()) {
-                       m_PendingServices.erase(it);
-                       m_IdleServices.insert(service);
-                       m_CV.notify_all();
-               }
+       /* remove the service from the list of pending services; if it's not in the
+        * list this was a manual (i.e. forced) check and we must not re-add the
+        * service to the services list because it's already there. */
+       CheckerComponent::ServiceSet::iterator it;
+       it = m_PendingServices.find(service);
+       if (it != m_PendingServices.end()) {
+               m_PendingServices.erase(it);
+               m_IdleServices.insert(service);
+               m_CV.notify_all();
        }
 
        Logger::Write(LogDebug, "checker", "Check finished for service '" + service->GetName() + "'");
@@ -195,20 +181,18 @@ void CheckerComponent::ResultTimerHandler(void)
 
 void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
 {
+       boost::mutex::scoped_lock lock(m_Mutex);
+
        ObjectLock olock(service); /* also required for the key extractor */
        String checker = service->GetChecker();
 
        if (checker == EndpointManager::GetInstance()->GetIdentity() || checker == m_Endpoint->GetName()) {
-               boost::mutex::scoped_lock lock(m_Mutex);
-
                if (m_PendingServices.find(service) != m_PendingServices.end())
                        return;
 
                m_IdleServices.insert(service);
                m_CV.notify_all();
        } else {
-               boost::mutex::scoped_lock lock(m_Mutex);
-
                m_IdleServices.erase(service);
                m_PendingServices.erase(service);
                m_CV.notify_all();
@@ -217,20 +201,20 @@ void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
 
 void CheckerComponent::NextCheckChangedHandler(const Service::Ptr& service)
 {
-       {
-               ObjectLock olock(service); /* required for the key extractor */
-               boost::mutex::scoped_lock lock(m_Mutex);
+       boost::mutex::scoped_lock lock(m_Mutex);
+
+       ObjectLock olock(service); /* required for the key extractor */
 
-               /* remove and re-insert the service from the set in order to force an index update */
-               typedef nth_index<ServiceSet, 0>::type ServiceView;
-               ServiceView& idx = boost::get<0>(m_IdleServices);
+       /* remove and re-insert the service from the set in order to force an index update */
+       typedef nth_index<ServiceSet, 0>::type ServiceView;
+       ServiceView& idx = boost::get<0>(m_IdleServices);
 
-               ServiceView::iterator it = idx.find(service);
-               if (it == idx.end())
-                       return;
+       ServiceView::iterator it = idx.find(service);
+       if (it == idx.end())
+               return;
 
-               idx.replace(it, service);
-               m_CV.notify_all();
-       }
+       idx.erase(service);
+       idx.insert(service);
+       m_CV.notify_all();
 }
 
index f1bc33f51055ad5a51bcbc8a7ecbba94d7884be2..386568fd2594f50c11bee421fbff5651c1097dc6 100644 (file)
@@ -89,10 +89,17 @@ AC_ARG_ENABLE(debug, [  --enable-debug=[no/yes]   turn on debugging (default=no)
 if test "x$enable_debug" = "xyes"; then
         CFLAGS="$CFLAGS -g -O0"
         CXXFLAGS="$CXXFLAGS -g -O0"
-        AC_MSG_RESULT(yes)
-else
-        AC_MSG_RESULT(no)
 fi
+AC_MSG_RESULT($enable_debug)
+
+AC_MSG_CHECKING(whether to enable GCC precompiled headers)
+AC_ARG_ENABLE(pch, [  --enable-pch=[no/yes]    enable GCC precompiled headers (default=no)],, enable_pch=no)
+AM_CONDITIONAL([USE_PCH], [test "x$enable_pch" = "xyes"])
+if test "x$enable_pch" = "xyes"; then
+       CFLAGS="$CFLAGS -fpch-deps -fpch-preprocess -Winvalid-pch"
+       CXXFLAGS="$CXXFLAGS -fpch-deps -fpch-preprocess -Winvalid-pch"
+fi
+AC_MSG_RESULT($enable_pch)
 
 AS_AC_EXPAND([ICINGA_PREFIX], $prefix)
 AC_DEFINE_UNQUOTED([ICINGA_PREFIX], "$ICINGA_PREFIX", [The installation prefix.])
index 60ffcb8ccd7e6020f10c6c9402ef0c7e3f486f60..721504a35e8b4681d11c80b1b0c8a47259a3f3ee 100644 (file)
@@ -106,3 +106,16 @@ libbase_la_LIBADD = \
        ${top_builddir}/third-party/mmatch/libmmatch.la \
        ${top_builddir}/third-party/cJSON/libcJSON.la \
        ${top_builddir}/third-party/popen-noshell/libpopen_noshell.la
+
+if USE_PCH
+BUILT_SOURCES = i2-base.h.gch
+
+i2-base.h.gch: i2-base.h
+       $(AM_V_CXX)$(LTCXXCOMPILE) $(libbase_la_CPPFLAGS) -o $@ $^
+
+libbase_la_DEPENDENCIES = \
+       i2-base.h.gch
+
+clean-local:
+       rm -f i2-base.h.gch
+endif
index 952b80c69c5b532c87f6ebf3e38593320fe7d689..8cc0cc271546cdec80c489628db5f0c3fa787424 100644 (file)
@@ -30,7 +30,6 @@ String Application::m_PkgLibDir;
 String Application::m_PkgDataDir;
 int Application::m_ArgC;
 char **Application::m_ArgV;
-EventQueue Application::m_EQ;
 
 /**
  * Constructor for the Application class.
@@ -122,7 +121,7 @@ void Application::ProfileTimerHandler(void)
 void Application::ShutdownTimerHandler(void)
 {
        if (m_ShuttingDown)
-               m_EQ.Stop();
+               GetEQ().Stop();
 }
 
 /**
@@ -565,5 +564,6 @@ void Application::SetPkgDataDir(const String& path)
  */
 EventQueue& Application::GetEQ(void)
 {
-       return m_EQ;
+       static EventQueue queue;
+       return queue;
 }
index dd6679122ee3c27dd57faccf8a24c25186d44643..bfeb4ef53d0066dfe601b2013790b7d4f535b092 100644 (file)
@@ -97,7 +97,6 @@ private:
        static String m_LocalStateDir; /**< The local state dir. */
        static String m_PkgLibDir; /**< The package lib dir. */
        static String m_PkgDataDir; /**< The package data dir. */
-       static EventQueue m_EQ; /**< The main thread's event queue. */
 
 #ifndef _WIN32
        static void SigIntHandler(int signum);
index d898a0c3d502c326436dd850e9845637f29294a2..ce39a2b402c835ba3bd0670aee827546d11cd41b 100644 (file)
@@ -111,6 +111,10 @@ private:
  */
 struct ObjectLock {
 public:
+       ObjectLock(void)
+               : m_Lock()
+       { }
+
        ObjectLock(const Object::Ptr& object)
                : m_Lock()
        {
@@ -125,6 +129,10 @@ public:
                        m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
        }
 
+       void Unlock(void)
+       {
+               m_Lock = recursive_mutex::scoped_lock();
+       }
 
 private:
        recursive_mutex::scoped_lock m_Lock;
index 18ad41c77c0a66656aeb9df352110936747b0c10..796f0ba1cf4d8e2bbb5f736df6984b79503a297d 100644 (file)
@@ -46,3 +46,17 @@ libconfig_la_LDFLAGS = \
 
 libconfig_la_LIBADD = \
        ${top_builddir}/lib/base/libbase.la
+
+if USE_PCH
+BUILT_SOURCES += i2-config.h.gch
+
+i2-config.h.gch: i2-config.h
+       $(AM_V_CXX)$(LTCXXCOMPILE) $(libconfig_la_CPPFLAGS) -o $@ $^
+
+libconfig_la_DEPENDENCIES = \
+       i2-config.h.gch
+
+clean-local:
+       rm -f i2-config.h.gch
+endif
+
index 9e09a230c00ac27ed2fcc440f8deb00c6f3238f1..7dc43187451a562faca6652eb609598a8909f930 100644 (file)
@@ -61,3 +61,17 @@ libicinga_la_LIBADD = \
        ${top_builddir}/lib/base/libbase.la \
        ${top_builddir}/lib/config/libconfig.la \
        ${top_builddir}/lib/remoting/libremoting.la
+
+if USE_PCH
+BUILT_SOURCES = i2-icinga.h.gch
+
+i2-icinga.h.gch: i2-icinga.h
+       $(AM_V_CXX)$(LTCXXCOMPILE) $(libicinga_la_CPPFLAGS) -o $@ $^
+
+libicinga_la_DEPENDENCIES = \
+       i2-icinga.h.gch
+
+clean-local:
+       rm -f i2-icinga.h.gch
+endif
+
index 579d6b92b983ebb3cacdc5aad8309b6c297550e6..3db70d3fdbe90ee8fe82e8745880ac1eef79d2e1 100644 (file)
@@ -506,6 +506,8 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
         * just in case there was no check result. */
        UpdateNextCheck();
 
+       olock.Unlock();
+
        callback();
 }
 
index d314d69683ed340f3fe038ab4c5b6d16f0805778..36080d860ad49103caf4ff6ef6356bf5b6e0dd76 100644 (file)
@@ -32,4 +32,18 @@ libpython_la_LIBADD = \
        ${top_builddir}/lib/base/libbase.la \
        ${top_builddir}/lib/config/libconfig.la \
        ${top_builddir}/lib/remoting/libremoting.la
+
+if USE_PCH
+BUILT_SOURCES = i2-python.h.gch
+
+i2-python.h.gch: i2-python.h
+       $(AM_V_CXX)$(LTCXXCOMPILE) $(libpython_la_CPPFLAGS) -o $@ $^
+
+libpython_la_DEPENDENCIES = \
+       i2-python.h.gch
+
+clean-local:
+       rm -f i2-python.h.gch
+endif
+
 endif
index 372dcca81541fe0d079bf5b9e0aae3c103c3c146..84e32b6fa012283e9923c05ad5608a3554425e21 100644 (file)
@@ -35,3 +35,17 @@ libremoting_la_LDFLAGS = \
 libremoting_la_LIBADD = \
        ${top_builddir}/lib/base/libbase.la \
        ${top_builddir}/lib/config/libconfig.la
+
+if USE_PCH
+BUILT_SOURCES = i2-remoting.h.gch
+
+i2-remoting.h.gch: i2-remoting.h
+       $(AM_V_CXX)$(LTCXXCOMPILE) $(libremoting_la_CPPFLAGS) -o $@ $^
+
+libremoting_la_DEPENDENCIES = \
+       i2-remoting.h.gch
+
+clean-local:
+       rm -f i2-remoting.h.gch
+endif
+
diff --git a/libtool-pch.patch b/libtool-pch.patch
new file mode 100644 (file)
index 0000000..2f1aac2
--- /dev/null
@@ -0,0 +1,26 @@
+--- m4/ltmain.sh       2013-02-21 11:23:30.000000000 +0100
++++ m4/ltmain.sh       2013-02-21 11:36:37.000000000 +0100
+@@ -2507,6 +2507,7 @@
+     case $libobj in
+     *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
++    *.gch) obj=$libobj ;;
+     *)
+       func_fatal_error "cannot determine name of library object from \`$libobj'"
+       ;;
+@@ -2717,7 +2718,14 @@
+     fi
+     $opt_dry_run || {
+-      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
++      case $libobj in
++      *.gch)
++        ln -sF "$objdir/$objname" "$libobj"
++        ;;
++      *)
++        func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
++        ;;
++      esac
+       # Unlock the critical section if it was locked
+       if test "$need_locks" != no; then