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

fix(coreav): prevent racy access to call variable

(cherry picked from commit c507d2665d)
This commit is contained in:
sudden6 2020-01-29 22:21:42 +01:00 committed by Anthony Bilinski
parent 26fcea0639
commit dfeca3e906
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C

View File

@ -732,9 +732,10 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid
state |= TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V; state |= TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V;
it.first->second->setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state)); it.first->second->setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state));
// Must explicitely unlock, because a deadlock can happen via ChatForm/Audio
locker.unlock(); locker.unlock();
emit reinterpret_cast<CoreAV*>(self)->avInvite(friendNum, video); emit self->avInvite(friendNum, video);
} }
void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, void* vSelf) void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, void* vSelf)
@ -742,6 +743,7 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
Q_UNUSED(toxav); Q_UNUSED(toxav);
CoreAV* self = static_cast<CoreAV*>(vSelf); CoreAV* self = static_cast<CoreAV*>(vSelf);
// we must unlock this lock before emitting any signals
QWriteLocker locker{&self->callsLock}; QWriteLocker locker{&self->callsLock};
auto it = self->calls.find(friendNum); auto it = self->calls.find(friendNum);
@ -766,14 +768,18 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
// If our state was null, we started the call and were still ringing // If our state was null, we started the call and were still ringing
if (!call.getState() && state) { if (!call.getState() && state) {
call.setActive(true); call.setActive(true);
bool videoEnabled = call.getVideoEnabled();
call.setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state));
locker.unlock(); locker.unlock();
emit self->avStart(friendNum, call.getVideoEnabled()); emit self->avStart(friendNum, videoEnabled);
} else if ((call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V) } else if ((call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V)
&& !(state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) { && !(state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) {
qDebug() << "Friend" << friendNum << "stopped sending video"; qDebug() << "Friend" << friendNum << "stopped sending video";
if (call.getVideoSource()) { if (call.getVideoSource()) {
call.getVideoSource()->stopSource(); call.getVideoSource()->stopSource();
} }
call.setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state));
} else if (!(call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V) } else if (!(call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V)
&& (state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) { && (state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) {
// Workaround toxav sometimes firing callbacks for "send last frame" -> "stop sending // Workaround toxav sometimes firing callbacks for "send last frame" -> "stop sending
@ -784,9 +790,9 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
if (call.getVideoSource()) { if (call.getVideoSource()) {
call.getVideoSource()->restartSource(); call.getVideoSource()->restartSource();
} }
}
call.setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state)); call.setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state));
}
} }
} }