[icinga-checkins] icinga.org: icinga2/master: Fine-grained locks (WIP, Part 4).

git at icinga.org git at icinga.org
Tue Feb 19 07:37:37 CET 2013


Module: icinga2
Branch: master
Commit: ecc95b3dc0c975f97755706e8aef68f4491620f8
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=ecc95b3dc0c975f97755706e8aef68f4491620f8

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Tue Feb 19 07:26:52 2013 +0100

Fine-grained locks (WIP, Part 4).

---

 lib/base/dynamicobject.cpp            |    9 +++------
 lib/base/dynamicobject.h              |    4 ++--
 lib/base/scripttask.cpp               |    1 -
 lib/icinga/api.cpp                    |    5 ++++-
 lib/icinga/notification.cpp           |   11 +++++------
 lib/icinga/nullchecktask.cpp          |    5 ++++-
 lib/icinga/pluginchecktask.cpp        |   11 +++++++++--
 lib/icinga/pluginnotificationtask.cpp |   11 +++++++++--
 lib/icinga/service-check.cpp          |   21 +++++----------------
 9 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp
index d66a342..c4683e1 100644
--- a/lib/base/dynamicobject.cpp
+++ b/lib/base/dynamicobject.cpp
@@ -353,8 +353,8 @@ void DynamicObject::Unregister(void)
 	OnUnregistered(GetSelf());
 }
 
-ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
-    const vector<Value>& arguments, ScriptTask::CompletionCallback callback)
+ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
+    const vector<Value>& arguments)
 {
 	Value value = Get("methods");
 
@@ -377,10 +377,7 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
 	if (!func)
 		BOOST_THROW_EXCEPTION(invalid_argument("Function '" + funcName + "' does not exist."));
 
-	ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments);
-	task->Start(callback);
-
-	return task;
+	return boost::make_shared<ScriptTask>(func, arguments);
 }
 
 /*
diff --git a/lib/base/dynamicobject.h b/lib/base/dynamicobject.h
index 385d4a1..8e1b556 100644
--- a/lib/base/dynamicobject.h
+++ b/lib/base/dynamicobject.h
@@ -100,8 +100,8 @@ public:
 	static signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
 	static signals2::signal<void (double, const set<DynamicObject *>&)> OnTransactionClosing;
 
-	ScriptTask::Ptr InvokeMethod(const String& method,
-	    const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
+	ScriptTask::Ptr MakeMethodTask(const String& method,
+	    const vector<Value>& arguments);
 
 	shared_ptr<DynamicType> GetType(void) const;
 	String GetName(void) const;
diff --git a/lib/base/scripttask.cpp b/lib/base/scripttask.cpp
index e771001..5ef9030 100644
--- a/lib/base/scripttask.cpp
+++ b/lib/base/scripttask.cpp
@@ -29,6 +29,5 @@ ScriptTask::ScriptTask(const ScriptFunction::Ptr& function,
 
 void ScriptTask::Run(void)
 {
-	ObjectLock olock(this);
 	m_Function->Invoke(GetSelf(), m_Arguments);
 }
diff --git a/lib/icinga/api.cpp b/lib/icinga/api.cpp
index 4317969..f454174 100644
--- a/lib/icinga/api.cpp
+++ b/lib/icinga/api.cpp
@@ -35,5 +35,8 @@ void API::GetAnswerToEverything(const ScriptTask::Ptr& task, const vector<Value>
 
 	Logger::Write(LogInformation, "icinga", "Hello from the Icinga 2 API: " + text);
 
-	task->FinishResult(42);
+	{
+		ObjectLock olock(task);
+		task->FinishResult(42);
+	}
 }
diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp
index 685b0b3..1c080b6 100644
--- a/lib/icinga/notification.cpp
+++ b/lib/icinga/notification.cpp
@@ -75,8 +75,8 @@ void Notification::SendNotification(NotificationType type)
 	vector<Value> arguments;
 	arguments.push_back(static_cast<Notification::Ptr>(GetSelf()));
 	arguments.push_back(type);
-	ScriptTask::Ptr task;
-	task = InvokeMethod("notify", arguments, boost::bind(&Notification::NotificationCompletedHandler, this, _1));
+
+	ScriptTask::Ptr task = MakeMethodTask("notify", arguments);
 
 	if (!task) {
 		Logger::Write(LogWarning, "icinga", "Notification object '" + GetName() + "' doesn't have a 'notify' method.");
@@ -84,11 +84,10 @@ void Notification::SendNotification(NotificationType type)
 		return;
 	}
 
-	if (!task->IsFinished()) {
-		/* We need to keep the task object alive until the completion handler is called. */
+	/* We need to keep the task object alive until the completion handler is called. */
+	m_Tasks.insert(task);
 
-		m_Tasks.insert(task);
-	}
+	task->Start(boost::bind(&Notification::NotificationCompletedHandler, this, _1));
 }
 
 void Notification::NotificationCompletedHandler(const ScriptTask::Ptr& task)
diff --git a/lib/icinga/nullchecktask.cpp b/lib/icinga/nullchecktask.cpp
index 5e38d84..01d26ca 100644
--- a/lib/icinga/nullchecktask.cpp
+++ b/lib/icinga/nullchecktask.cpp
@@ -31,5 +31,8 @@ void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>&
 	Dictionary::Ptr cr = boost::make_shared<Dictionary>();
 	cr->Set("state", StateUnknown);
 
-	task->FinishResult(cr);
+	{
+		ObjectLock olock(task);
+		task->FinishResult(cr);
+	}
 }
diff --git a/lib/icinga/pluginchecktask.cpp b/lib/icinga/pluginchecktask.cpp
index d69e622..38aa653 100644
--- a/lib/icinga/pluginchecktask.cpp
+++ b/lib/icinga/pluginchecktask.cpp
@@ -79,7 +79,11 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
 	try {
 		pr = ct.m_Process->GetResult();
 	} catch (...) {
-		ct.m_Task->FinishException(boost::current_exception());
+		{
+			ObjectLock olock(ct.m_Task);
+			ct.m_Task->FinishException(boost::current_exception());
+		}
+
 		return;
 	}
 
@@ -90,7 +94,10 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
 	result->Set("execution_start", pr.ExecutionStart);
 	result->Set("execution_end", pr.ExecutionEnd);
 
-	ct.m_Task->FinishResult(result);
+	{
+		ObjectLock olock(ct.m_Task);
+		ct.m_Task->FinishResult(result);
+	}
 }
 
 ServiceState PluginCheckTask::ExitStatusToState(int exitStatus)
diff --git a/lib/icinga/pluginnotificationtask.cpp b/lib/icinga/pluginnotificationtask.cpp
index 96b84d7..4832ec5 100644
--- a/lib/icinga/pluginnotificationtask.cpp
+++ b/lib/icinga/pluginnotificationtask.cpp
@@ -107,9 +107,16 @@ void PluginNotificationTask::ProcessFinishedHandler(PluginNotificationTask ct)
 			Logger::Write(LogWarning, "icinga", msgbuf.str());
 		}
 
-		ct.m_Task->FinishResult(Empty);
+		{
+			ObjectLock olock(ct.m_Task);
+			ct.m_Task->FinishResult(Empty);
+		}
 	} catch (...) {
-		ct.m_Task->FinishException(boost::current_exception());
+		{
+			ObjectLock olock(ct.m_Task);
+			ct.m_Task->FinishException(boost::current_exception());
+		}
+
 		return;
 	}
 }
diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp
index aab1d9f..0fcab97 100644
--- a/lib/icinga/service-check.cpp
+++ b/lib/icinga/service-check.cpp
@@ -435,24 +435,13 @@ void Service::BeginExecuteCheck(const function<void (void)>& callback)
 	scheduleInfo->Set("schedule_start", GetNextCheck());
 	scheduleInfo->Set("execution_start", Utility::GetTime());
 
-	try {
-		vector<Value> arguments;
-		arguments.push_back(static_cast<Service::Ptr>(GetSelf()));
-		ScriptTask::Ptr task;
-		task = InvokeMethod("check", arguments, boost::bind(&Service::CheckCompletedHandler, this, scheduleInfo, _1, callback));
-
-		if (!task->IsFinished())
-			Set("current_task", task);
-	} catch (...) {
-		/* something went wrong while setting up the method call -
-		 * reschedule the service and call the callback anyway. */
-
-		UpdateNextCheck();
+	vector<Value> arguments;
+	arguments.push_back(static_cast<Service::Ptr>(GetSelf()));
 
-		callback();
+	ScriptTask::Ptr task = MakeMethodTask("check", arguments);
+	Set("current_task", task);
 
-		throw;
-	}
+	task->Start(boost::bind(&Service::CheckCompletedHandler, this, scheduleInfo, _1, callback));
 }
 
 void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,





More information about the icinga-checkins mailing list