From ecc95b3dc0c975f97755706e8aef68f4491620f8 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 19 Feb 2013 07:26:52 +0100 Subject: [PATCH] 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 d66a3426c..c4683e1be 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& arguments, ScriptTask::CompletionCallback callback) +ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method, + const vector& 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(func, arguments); - task->Start(callback); - - return task; + return boost::make_shared(func, arguments); } /* diff --git a/lib/base/dynamicobject.h b/lib/base/dynamicobject.h index 385d4a19d..8e1b5565d 100644 --- a/lib/base/dynamicobject.h +++ b/lib/base/dynamicobject.h @@ -100,8 +100,8 @@ public: static signals2::signal OnUnregistered; static signals2::signal&)> OnTransactionClosing; - ScriptTask::Ptr InvokeMethod(const String& method, - const vector& arguments, ScriptTask::CompletionCallback callback); + ScriptTask::Ptr MakeMethodTask(const String& method, + const vector& arguments); shared_ptr GetType(void) const; String GetName(void) const; diff --git a/lib/base/scripttask.cpp b/lib/base/scripttask.cpp index e771001fd..5ef9030b5 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 431796906..f4541745d 100644 --- a/lib/icinga/api.cpp +++ b/lib/icinga/api.cpp @@ -35,5 +35,8 @@ void API::GetAnswerToEverything(const ScriptTask::Ptr& task, const vector 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 685b0b3ce..1c080b604 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -75,8 +75,8 @@ void Notification::SendNotification(NotificationType type) vector arguments; arguments.push_back(static_cast(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 5e38d8465..01d26ca7c 100644 --- a/lib/icinga/nullchecktask.cpp +++ b/lib/icinga/nullchecktask.cpp @@ -31,5 +31,8 @@ void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector& Dictionary::Ptr cr = boost::make_shared(); 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 d69e6228f..38aa653e7 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 96b84d769..4832ec500 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 aab1d9f72..0fcab976c 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -435,24 +435,13 @@ void Service::BeginExecuteCheck(const function& callback) scheduleInfo->Set("schedule_start", GetNextCheck()); scheduleInfo->Set("execution_start", Utility::GetTime()); - try { - vector arguments; - arguments.push_back(static_cast(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 arguments; + arguments.push_back(static_cast(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, -- 2.40.0