1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Fix call race leading to deadlock and memory leak

A call cancel/accepted race was locking up both UI and AV threads, while the stream thread was shoveling more and more video frames on the AV thread's event queue
This commit is contained in:
tux3 2015-10-25 00:17:22 +02:00
parent f85aec6c95
commit c902543ae4
No known key found for this signature in database
GPG Key ID: 7E086DD661263264

View File

@ -504,6 +504,9 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
// Run this slow path callback asynchronously on the AV thread to avoid deadlocks
if (QThread::currentThread() != self->coreavThread.get())
{
// We assume the original caller doesn't come from the CoreAV thread here
while (self->threadSwitchLock.test_and_set(std::memory_order_acquire))
QThread::yieldCurrentThread(); // Shouldn't spin for long, we have priority
return (void)QMetaObject::invokeMethod(self, "stateCallback", Qt::QueuedConnection,
Q_ARG(ToxAV*, toxav), Q_ARG(uint32_t, friendNum),
Q_ARG(uint32_t, state), Q_ARG(void*, _self));
@ -512,6 +515,7 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
if(!self->calls.contains(friendNum))
{
qWarning() << QString("stateCallback called, but call %1 is already dead").arg(friendNum);
self->threadSwitchLock.clear(std::memory_order_release);
return;
}
ToxFriendCall& call = self->calls[friendNum];
@ -554,6 +558,7 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
call.state = static_cast<TOXAV_FRIEND_CALL_STATE>(state);
}
self->threadSwitchLock.clear(std::memory_order_release);
}
void CoreAV::bitrateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t arate, uint32_t vrate, void *_self)