From dfda90f744763cab1c0f53f736a98da870f72dcc Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 19 Jul 2013 10:34:46 +0200 Subject: [PATCH] ido_mysql: Fix deadlock. --- components/ido_mysql/mysqldbconnection.cpp | 138 +++++++++++---------- 1 file changed, 70 insertions(+), 68 deletions(-) diff --git a/components/ido_mysql/mysqldbconnection.cpp b/components/ido_mysql/mysqldbconnection.cpp index e4e71a092..24037b554 100644 --- a/components/ido_mysql/mysqldbconnection.cpp +++ b/components/ido_mysql/mysqldbconnection.cpp @@ -74,78 +74,80 @@ void MysqlDbConnection::TxTimerHandler(void) void MysqlDbConnection::ReconnectTimerHandler(void) { - boost::mutex::scoped_lock lock(m_ConnectionMutex); + { + boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (m_Connected) { - /* Check if we're really still connected */ - if (mysql_ping(&m_Connection) == 0) - return; + if (m_Connected) { + /* Check if we're really still connected */ + if (mysql_ping(&m_Connection) == 0) + return; - mysql_close(&m_Connection); - m_Connected = false; + mysql_close(&m_Connection); + 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(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(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(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(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(); }