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:
@@ -35,21 +35,32 @@ void SqlTransaction::Execute(Database *db)
|
|||||||
{
|
{
|
||||||
const char* sql;
|
const char* sql;
|
||||||
|
|
||||||
|
if (m_queue.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
db->DirectExecute("START TRANSACTION");
|
db->DirectExecute("START TRANSACTION");
|
||||||
while (m_queue.next(sql))
|
while (!m_queue.empty())
|
||||||
{
|
{
|
||||||
|
sql = m_queue.peek();
|
||||||
|
m_queue.unlock();
|
||||||
if (!db->DirectExecute(sql))
|
if (!db->DirectExecute(sql))
|
||||||
{
|
{
|
||||||
free((void*)const_cast<char*>(sql));
|
free((void*)const_cast<char*>(sql));
|
||||||
|
m_queue.pop_front();
|
||||||
db->DirectExecute("ROLLBACK");
|
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));
|
free((void*)const_cast<char*>(sql));
|
||||||
|
m_queue.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free((void*)const_cast<char*>(sql));
|
free((void*)const_cast<char*>(sql));
|
||||||
|
m_queue.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
db->DirectExecute("COMMIT");
|
db->DirectExecute("COMMIT");
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ namespace ACE_Based
|
|||||||
{
|
{
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
|
|
||||||
T& result = _queue.front();
|
T& result = _queue.front();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -121,6 +120,20 @@ namespace ACE_Based
|
|||||||
{
|
{
|
||||||
this->_lock.release();
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user