]> granicus.if.org Git - icinga2/commitdiff
Fine-grained locks (WIP, Part 4).
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 19 Feb 2013 06:26:52 +0000 (07:26 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 19 Feb 2013 06:26:52 +0000 (07:26 +0100)
lib/base/dynamicobject.cpp
lib/base/dynamicobject.h
lib/base/scripttask.cpp
lib/icinga/api.cpp
lib/icinga/notification.cpp
lib/icinga/nullchecktask.cpp
lib/icinga/pluginchecktask.cpp
lib/icinga/pluginnotificationtask.cpp
lib/icinga/service-check.cpp

index d66a3426c3c114429686ef5f55cf0ab2ab04c97a..c4683e1beda42e106d4785655976427ad6992685 100644 (file)
@@ -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);
 }
 
 /*
index 385d4a19d2198019d4c4b5e205ea789de8dd5f57..8e1b5565dd14c777c2e4cec26eec2fb09b331dde 100644 (file)
@@ -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;
index e771001fd9804e83a623771dd7a09b6800e546be..5ef9030b5542e3c6cdcfea87f3ed50b1bbf6875f 100644 (file)
@@ -29,6 +29,5 @@ ScriptTask::ScriptTask(const ScriptFunction::Ptr& function,
 
 void ScriptTask::Run(void)
 {
-       ObjectLock olock(this);
        m_Function->Invoke(GetSelf(), m_Arguments);
 }
index 4317969064f8830cd654c8763902ea8a565730bc..f4541745d18c233d8c3d07ad7cfe8a6b25082a99 100644 (file)
@@ -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);
+       }
 }
index 685b0b3ce9d97eb17142ea8ca33621901519a4e1..1c080b604de64ceebd86060feae97bacd30c72ff 100644 (file)
@@ -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)
index 5e38d8465de313c6ebfd1cd66694e190fd8f6b8f..01d26ca7cdf2d9efc6168b8814017d2af9317a07 100644 (file)
@@ -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);
+       }
 }
index d69e6228f60d69d78ff35ea43e92e4cb8e350668..38aa653e771b37e2167d76425df4a7439a9d057e 100644 (file)
@@ -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)
index 96b84d76940d7ea5eafe0e3ecb433e358b32f31c..4832ec50049b612d05a0a3b19c89f558f1c6ca96 100644 (file)
@@ -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;
        }
 }
index aab1d9f72717c8272ec4a11c2ba9636351f5365f..0fcab976c4e262dba3100eb23771e3aeec2bc586 100644 (file)
@@ -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,