aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMachiavelli <none@none>2010-05-16 13:31:52 +0200
committerMachiavelli <none@none>2010-05-16 13:31:52 +0200
commit437a5d90b227921f84ce9b9ed11047b27ed09f17 (patch)
treed59d285581b8664b93f9fe8727f2bf3ff804f080 /src
parent89887b9b6554656033079bd3c90e1495fb9edf74 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/shared/Database/SqlOperations.cpp15
-rw-r--r--src/shared/LockedQueue.h15
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<char*>(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<char*>(sql));
+ m_queue.pop_front();
}
+
return;
}
free((void*)const_cast<char*>(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