Browse Source

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
pull/2476/head
tux3 10 years ago
parent
commit
c902543ae4
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
  1. 5
      src/core/coreav.cpp

5
src/core/coreav.cpp

@ -504,6 +504,9 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi @@ -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 @@ -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 @@ -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)

Loading…
Cancel
Save