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
This commit is contained in:
Machiavelli
2010-05-16 13:31:52 +02:00
parent 89887b9b65
commit 437a5d90b2
2 changed files with 27 additions and 3 deletions
+13 -2
View File
@@ -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");
+14 -1
View File
@@ -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