mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 14:44:32 +02:00
Fine-grained locks (WIP, Part 4).
This commit is contained in:
parent
3dace35cf1
commit
ecc95b3dc0
@ -353,8 +353,8 @@ void DynamicObject::Unregister(void)
|
|||||||
OnUnregistered(GetSelf());
|
OnUnregistered(GetSelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
|
ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
|
||||||
const vector<Value>& arguments, ScriptTask::CompletionCallback callback)
|
const vector<Value>& arguments)
|
||||||
{
|
{
|
||||||
Value value = Get("methods");
|
Value value = Get("methods");
|
||||||
|
|
||||||
@ -377,10 +377,7 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
|
|||||||
if (!func)
|
if (!func)
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Function '" + funcName + "' does not exist."));
|
BOOST_THROW_EXCEPTION(invalid_argument("Function '" + funcName + "' does not exist."));
|
||||||
|
|
||||||
ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments);
|
return boost::make_shared<ScriptTask>(func, arguments);
|
||||||
task->Start(callback);
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -100,8 +100,8 @@ public:
|
|||||||
static signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
|
static signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
|
||||||
static signals2::signal<void (double, const set<DynamicObject *>&)> OnTransactionClosing;
|
static signals2::signal<void (double, const set<DynamicObject *>&)> OnTransactionClosing;
|
||||||
|
|
||||||
ScriptTask::Ptr InvokeMethod(const String& method,
|
ScriptTask::Ptr MakeMethodTask(const String& method,
|
||||||
const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
|
const vector<Value>& arguments);
|
||||||
|
|
||||||
shared_ptr<DynamicType> GetType(void) const;
|
shared_ptr<DynamicType> GetType(void) const;
|
||||||
String GetName(void) const;
|
String GetName(void) const;
|
||||||
|
@ -29,6 +29,5 @@ ScriptTask::ScriptTask(const ScriptFunction::Ptr& function,
|
|||||||
|
|
||||||
void ScriptTask::Run(void)
|
void ScriptTask::Run(void)
|
||||||
{
|
{
|
||||||
ObjectLock olock(this);
|
|
||||||
m_Function->Invoke(GetSelf(), m_Arguments);
|
m_Function->Invoke(GetSelf(), m_Arguments);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
Logger::Write(LogInformation, "icinga", "Hello from the Icinga 2 API: " + text);
|
||||||
|
|
||||||
task->FinishResult(42);
|
{
|
||||||
|
ObjectLock olock(task);
|
||||||
|
task->FinishResult(42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ void Notification::SendNotification(NotificationType type)
|
|||||||
vector<Value> arguments;
|
vector<Value> arguments;
|
||||||
arguments.push_back(static_cast<Notification::Ptr>(GetSelf()));
|
arguments.push_back(static_cast<Notification::Ptr>(GetSelf()));
|
||||||
arguments.push_back(type);
|
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) {
|
if (!task) {
|
||||||
Logger::Write(LogWarning, "icinga", "Notification object '" + GetName() + "' doesn't have a 'notify' method.");
|
Logger::Write(LogWarning, "icinga", "Notification object '" + GetName() + "' doesn't have a 'notify' method.");
|
||||||
@ -84,11 +84,10 @@ void Notification::SendNotification(NotificationType type)
|
|||||||
return;
|
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)
|
void Notification::NotificationCompletedHandler(const ScriptTask::Ptr& task)
|
||||||
|
@ -31,5 +31,8 @@ void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>&
|
|||||||
Dictionary::Ptr cr = boost::make_shared<Dictionary>();
|
Dictionary::Ptr cr = boost::make_shared<Dictionary>();
|
||||||
cr->Set("state", StateUnknown);
|
cr->Set("state", StateUnknown);
|
||||||
|
|
||||||
task->FinishResult(cr);
|
{
|
||||||
|
ObjectLock olock(task);
|
||||||
|
task->FinishResult(cr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,11 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
|||||||
try {
|
try {
|
||||||
pr = ct.m_Process->GetResult();
|
pr = ct.m_Process->GetResult();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ct.m_Task->FinishException(boost::current_exception());
|
{
|
||||||
|
ObjectLock olock(ct.m_Task);
|
||||||
|
ct.m_Task->FinishException(boost::current_exception());
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +94,10 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
|||||||
result->Set("execution_start", pr.ExecutionStart);
|
result->Set("execution_start", pr.ExecutionStart);
|
||||||
result->Set("execution_end", pr.ExecutionEnd);
|
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)
|
ServiceState PluginCheckTask::ExitStatusToState(int exitStatus)
|
||||||
|
@ -107,9 +107,16 @@ void PluginNotificationTask::ProcessFinishedHandler(PluginNotificationTask ct)
|
|||||||
Logger::Write(LogWarning, "icinga", msgbuf.str());
|
Logger::Write(LogWarning, "icinga", msgbuf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ct.m_Task->FinishResult(Empty);
|
{
|
||||||
|
ObjectLock olock(ct.m_Task);
|
||||||
|
ct.m_Task->FinishResult(Empty);
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ct.m_Task->FinishException(boost::current_exception());
|
{
|
||||||
|
ObjectLock olock(ct.m_Task);
|
||||||
|
ct.m_Task->FinishException(boost::current_exception());
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,24 +435,13 @@ void Service::BeginExecuteCheck(const function<void (void)>& callback)
|
|||||||
scheduleInfo->Set("schedule_start", GetNextCheck());
|
scheduleInfo->Set("schedule_start", GetNextCheck());
|
||||||
scheduleInfo->Set("execution_start", Utility::GetTime());
|
scheduleInfo->Set("execution_start", Utility::GetTime());
|
||||||
|
|
||||||
try {
|
vector<Value> arguments;
|
||||||
vector<Value> arguments;
|
arguments.push_back(static_cast<Service::Ptr>(GetSelf()));
|
||||||
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())
|
ScriptTask::Ptr task = MakeMethodTask("check", arguments);
|
||||||
Set("current_task", task);
|
Set("current_task", task);
|
||||||
} catch (...) {
|
|
||||||
/* something went wrong while setting up the method call -
|
|
||||||
* reschedule the service and call the callback anyway. */
|
|
||||||
|
|
||||||
UpdateNextCheck();
|
task->Start(boost::bind(&Service::CheckCompletedHandler, this, scheduleInfo, _1, callback));
|
||||||
|
|
||||||
callback();
|
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
|
void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user