Fix race conditions in the config compiler.

Fixes #5335
This commit is contained in:
Gunnar Beutner 2013-12-14 23:10:37 +01:00
parent 4563bb355f
commit 0af81f2da2
6 changed files with 59 additions and 26 deletions

View File

@ -103,12 +103,12 @@ ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
return m_ExpressionList;
}
void ConfigItem::Link(void)
ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
{
ASSERT(OwnsLock());
if (m_LinkedExpressionList)
return;
return m_LinkedExpressionList;
m_LinkedExpressionList = make_shared<ExpressionList>();
@ -121,31 +121,25 @@ void ConfigItem::Link(void)
" exist (" << m_DebugInfo << ")";
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str());
} else {
parent->Link();
ExpressionList::Ptr pexprl;
{
ObjectLock olock(parent);
pexprl = parent->GetLinkedExpressionList();
}
ExpressionList::Ptr pexprl = parent->m_LinkedExpressionList;
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
}
}
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, m_ExpressionList, m_DebugInfo));
}
ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
{
ASSERT(OwnsLock());
if (!m_LinkedExpressionList)
Link();
return m_LinkedExpressionList;
}
Dictionary::Ptr ConfigItem::GetProperties(void)
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
ASSERT(OwnsLock());
if (!m_Properties) {
m_Properties = make_shared<Dictionary>();
@ -181,7 +175,13 @@ DynamicObject::Ptr ConfigItem::Commit(void)
if (IsAbstract())
return DynamicObject::Ptr();
Dictionary::Ptr properties = GetProperties();
Dictionary::Ptr properties;
{
ObjectLock olock(this);
properties = GetProperties();
}
DynamicObject::Ptr dobj = dtype->CreateObject(properties);
dobj->Register();

View File

@ -65,7 +65,6 @@ public:
static void DiscardItems(void);
private:
void Link(void);
ExpressionList::Ptr GetExpressionList(void) const;
String m_Type; /**< The object type. */

View File

@ -79,11 +79,21 @@ void ConfigType::ValidateItem(const ConfigItem::Ptr& item)
if (item->IsAbstract())
return;
Dictionary::Ptr attrs = item->GetProperties();
Dictionary::Ptr attrs;
DebugInfo debugInfo;
String type, name;
{
ObjectLock olock(item);
attrs = item->GetProperties();
debugInfo = item->GetDebugInfo();
type = item->GetType();
name = item->GetName();
}
std::vector<String> locations;
DebugInfo debugInfo = item->GetDebugInfo();
locations.push_back("Object '" + item->GetName() + "' (Type: '" + item->GetType() + "') at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine));
locations.push_back("Object '" + name + "' (Type: '" + type + "') at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine));
std::vector<TypeRuleList::Ptr> ruleLists;
AddParentRules(ruleLists, GetSelf());

View File

@ -155,8 +155,16 @@ void Host::UpdateSlaveServices(void)
path.push_back("services");
path.push_back(kv.first);
ExpressionList::Ptr exprl;
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
}
DebugInfo di;
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
exprl->FindDebugInfoPath(path, di);
if (di.Path.IsEmpty())
di = item->GetDebugInfo();
@ -185,7 +193,7 @@ void Host::UpdateSlaveServices(void)
/* Clone attributes from the service expression list. */
ExpressionList::Ptr svc_exprl = make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractPath(path, svc_exprl);
exprl->ExtractPath(path, svc_exprl);
builder->AddExpressionList(svc_exprl);

View File

@ -335,8 +335,16 @@ void Service::UpdateSlaveScheduledDowntimes(void)
path.push_back("scheduled_downtimes");
path.push_back(kv.first);
ExpressionList::Ptr exprl;
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
}
DebugInfo di;
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
exprl->FindDebugInfoPath(path, di);
if (di.Path.IsEmpty())
di = item->GetDebugInfo();
@ -361,7 +369,7 @@ void Service::UpdateSlaveScheduledDowntimes(void)
/* Clone attributes from the scheduled downtime expression list. */
ExpressionList::Ptr sd_exprl = make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractPath(path, sd_exprl);
exprl->ExtractPath(path, sd_exprl);
builder->AddExpressionList(sd_exprl);

View File

@ -114,8 +114,16 @@ void Service::UpdateSlaveNotifications(void)
path.push_back("notifications");
path.push_back(kv.first);
ExpressionList::Ptr exprl;
{
ObjectLock ilock(exprl);
exprl = item->GetLinkedExpressionList();
}
DebugInfo di;
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
exprl->FindDebugInfoPath(path, di);
if (di.Path.IsEmpty())
di = item->GetDebugInfo();
@ -140,7 +148,7 @@ void Service::UpdateSlaveNotifications(void)
/* Clone attributes from the notification expression list. */
ExpressionList::Ptr nfc_exprl = make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractPath(path, nfc_exprl);
exprl->ExtractPath(path, nfc_exprl);
builder->AddExpressionList(nfc_exprl);