ido_mysql: Fix deadlock.

This commit is contained in:
Gunnar Beutner 2013-07-19 10:34:46 +02:00
parent 8a99019146
commit dfda90f744
1 changed files with 70 additions and 68 deletions

View File

@ -74,78 +74,80 @@ void MysqlDbConnection::TxTimerHandler(void)
void MysqlDbConnection::ReconnectTimerHandler(void) void MysqlDbConnection::ReconnectTimerHandler(void)
{ {
boost::mutex::scoped_lock lock(m_ConnectionMutex); {
boost::mutex::scoped_lock lock(m_ConnectionMutex);
if (m_Connected) { if (m_Connected) {
/* Check if we're really still connected */ /* Check if we're really still connected */
if (mysql_ping(&m_Connection) == 0) if (mysql_ping(&m_Connection) == 0)
return; return;
mysql_close(&m_Connection); mysql_close(&m_Connection);
m_Connected = false; m_Connected = false;
}
String ihost, iuser, ipasswd, idb;
const char *host, *user , *passwd, *db;
long port;
ihost = m_Host;
iuser = m_User;
ipasswd = m_Password;
idb = m_Database;
host = (!ihost.IsEmpty()) ? ihost.CStr() : NULL;
port = m_Port;
user = (!iuser.IsEmpty()) ? iuser.CStr() : NULL;
passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : NULL;
db = (!idb.IsEmpty()) ? idb.CStr() : NULL;
if (!mysql_init(&m_Connection))
BOOST_THROW_EXCEPTION(std::bad_alloc());
if (!mysql_real_connect(&m_Connection, host, user, passwd, db, port, NULL, 0))
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
m_Connected = true;
String instanceName = "default";
if (!m_InstanceName.IsEmpty())
instanceName = m_InstanceName;
Array::Ptr rows = Query("SELECT instance_id FROM icinga_instances WHERE instance_name = '" + Escape(instanceName) + "'");
if (rows->GetLength() == 0) {
Query("INSERT INTO icinga_instances (instance_name, instance_description) VALUES ('" + Escape(instanceName) + "', '" + m_InstanceDescription + "')");
m_InstanceID = GetInsertID();
} else {
Dictionary::Ptr row = rows->Get(0);
m_InstanceID = DbReference(row->Get("instance_id"));
}
std::ostringstream msgbuf;
msgbuf << "MySQL IDO instance id: " << static_cast<long>(m_InstanceID);
Log(LogInformation, "ido_mysql", msgbuf.str());
Query("UPDATE icinga_objects SET is_active = 0");
std::ostringstream qbuf;
qbuf << "SELECT object_id, objecttype_id, name1, name2 FROM icinga_objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
rows = Query(qbuf.str());
ObjectLock olock(rows);
BOOST_FOREACH(const Dictionary::Ptr& row, rows) {
DbType::Ptr dbtype = DbType::GetByID(row->Get("objecttype_id"));
if (!dbtype)
continue;
DbObject::Ptr dbobj = dbtype->GetOrCreateObjectByName(row->Get("name1"), row->Get("name2"));
SetReference(dbobj, DbReference(row->Get("object_id")));
}
Query("BEGIN");
} }
String ihost, iuser, ipasswd, idb;
const char *host, *user , *passwd, *db;
long port;
ihost = m_Host;
iuser = m_User;
ipasswd = m_Password;
idb = m_Database;
host = (!ihost.IsEmpty()) ? ihost.CStr() : NULL;
port = m_Port;
user = (!iuser.IsEmpty()) ? iuser.CStr() : NULL;
passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : NULL;
db = (!idb.IsEmpty()) ? idb.CStr() : NULL;
if (!mysql_init(&m_Connection))
BOOST_THROW_EXCEPTION(std::bad_alloc());
if (!mysql_real_connect(&m_Connection, host, user, passwd, db, port, NULL, 0))
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
m_Connected = true;
String instanceName = "default";
if (!m_InstanceName.IsEmpty())
instanceName = m_InstanceName;
Array::Ptr rows = Query("SELECT instance_id FROM icinga_instances WHERE instance_name = '" + Escape(instanceName) + "'");
if (rows->GetLength() == 0) {
Query("INSERT INTO icinga_instances (instance_name, instance_description) VALUES ('" + Escape(instanceName) + "', '" + m_InstanceDescription + "')");
m_InstanceID = GetInsertID();
} else {
Dictionary::Ptr row = rows->Get(0);
m_InstanceID = DbReference(row->Get("instance_id"));
}
std::ostringstream msgbuf;
msgbuf << "MySQL IDO instance id: " << static_cast<long>(m_InstanceID);
Log(LogInformation, "ido_mysql", msgbuf.str());
Query("UPDATE icinga_objects SET is_active = 0");
std::ostringstream qbuf;
qbuf << "SELECT object_id, objecttype_id, name1, name2 FROM icinga_objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
rows = Query(qbuf.str());
ObjectLock olock(rows);
BOOST_FOREACH(const Dictionary::Ptr& row, rows) {
DbType::Ptr dbtype = DbType::GetByID(row->Get("objecttype_id"));
if (!dbtype)
continue;
DbObject::Ptr dbobj = dbtype->GetOrCreateObjectByName(row->Get("name1"), row->Get("name2"));
SetReference(dbobj, DbReference(row->Get("object_id")));
}
Query("BEGIN");
UpdateAllObjects(); UpdateAllObjects();
} }