From 437a5d90b227921f84ce9b9ed11047b27ed09f17 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sun, 16 May 2010 13:31:52 +0200 Subject: [PATCH] Fix a possible crash in SqlTransaction::Execute(), using post-iterating on the LockedQueue instead of pre-iterating. Thanks to click for the insight and Spp for testing. --HG-- branch : trunk --- src/shared/Database/SqlOperations.cpp | 15 +++++++++++++-- src/shared/LockedQueue.h | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp index c766d6ca21d..8894f896855 100644 --- a/src/shared/Database/SqlOperations.cpp +++ b/src/shared/Database/SqlOperations.cpp @@ -35,21 +35,32 @@ void SqlTransaction::Execute(Database *db) { const char* sql; + if (m_queue.empty()) + return; + db->DirectExecute("START TRANSACTION"); - while (m_queue.next(sql)) + while (!m_queue.empty()) { + sql = m_queue.peek(); + m_queue.unlock(); if (!db->DirectExecute(sql)) { free((void*)const_cast(sql)); + m_queue.pop_front(); db->DirectExecute("ROLLBACK"); - while (m_queue.next(sql)) + while (!m_queue.empty()) { + sql = m_queue.peek(); + m_queue.unlock(); free((void*)const_cast(sql)); + m_queue.pop_front(); } + return; } free((void*)const_cast(sql)); + m_queue.pop_front(); } db->DirectExecute("COMMIT"); diff --git a/src/shared/LockedQueue.h b/src/shared/LockedQueue.h index fd0a0d5d22d..9f8afae6c14 100644 --- a/src/shared/LockedQueue.h +++ b/src/shared/LockedQueue.h @@ -87,7 +87,6 @@ namespace ACE_Based { lock(); - T& result = _queue.front(); return result; @@ -121,6 +120,20 @@ namespace ACE_Based { this->_lock.release(); } + + ///! Calls pop_front of the queue + void pop_front() + { + ACE_GUARD (LockType, g, this->_lock); + _queue.pop_front(); + } + + ///! Checks if we're empty or not with locks held + bool empty() + { + ACE_GUARD_RETURN (LockType, g, this->_lock, false); + return _queue.empty(); + } }; } #endif