mirror of https://github.com/Icinga/icinga2.git
Fine-grained locks (WIP, Part 8).
This commit is contained in:
parent
5e91f6c54d
commit
4306c6c07a
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* 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);
|
||||
ObjectLock olock(service); /* required for the key extractor */
|
||||
|
||||
ServiceView::iterator it = idx.find(service);
|
||||
if (it == idx.end())
|
||||
return;
|
||||
/* 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);
|
||||
|
||||
idx.replace(it, service);
|
||||
m_CV.notify_all();
|
||||
}
|
||||
ServiceView::iterator it = idx.find(service);
|
||||
if (it == idx.end())
|
||||
return;
|
||||
|
||||
idx.erase(service);
|
||||
idx.insert(service);
|
||||
m_CV.notify_all();
|
||||
}
|
||||
|
||||
|
|
13
configure.ac
13
configure.ac
|
@ -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.])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -506,6 +506,8 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
|
|||
* just in case there was no check result. */
|
||||
UpdateNextCheck();
|
||||
|
||||
olock.Unlock();
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue