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

fix(calls): Fix SIGSEGV on quit while in call

On application close we used to access invalid memory associated with
the audio subsystem. This was because on destruction of static variables
we tried to access state associated with an already destructed item.

These variables seem to have no good reason to be static. They should be
tied to a single CoreAV instance and are only accessed through an
existing CoreAV instance.
This commit is contained in:
Mick Sayson 2019-11-10 18:56:30 -08:00 committed by Anthony Bilinski
parent 17bbe24ec5
commit 87eed97ab3
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
2 changed files with 20 additions and 20 deletions

View File

@ -68,18 +68,6 @@
* deadlock.
*/
/**
* @brief Maps friend IDs to ToxFriendCall.
* @note Need to use STL container here, because Qt containers need a copy constructor.
*/
std::map<uint32_t, CoreAV::ToxFriendCallPtr> CoreAV::calls;
/**
* @brief Maps group IDs to ToxGroupCalls.
* @note Need to use STL container here, because Qt containers need a copy constructor.
*/
std::map<int, CoreAV::ToxGroupCallPtr> CoreAV::groupCalls;
CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav)
: audio{nullptr}
, toxav{std::move(toxav)}
@ -789,12 +777,12 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
if (state & TOXAV_FRIEND_CALL_STATE_ERROR) {
qWarning() << "Call with friend" << friendNum << "died of unnatural causes!";
calls.erase(friendNum);
self->calls.erase(friendNum);
// why not self->
emit self->avEnd(friendNum, true);
} else if (state & TOXAV_FRIEND_CALL_STATE_FINISHED) {
qDebug() << "Call with friend" << friendNum << "finished quietly";
calls.erase(friendNum);
self->calls.erase(friendNum);
// why not self->
emit self->avEnd(friendNum);
} else {
@ -875,7 +863,7 @@ void CoreAV::audioFrameCallback(ToxAV*, uint32_t friendNum, const int16_t* pcm,
uint8_t channels, uint32_t samplingRate, void* vSelf)
{
CoreAV* self = static_cast<CoreAV*>(vSelf);
auto it = calls.find(friendNum);
auto it = self->calls.find(friendNum);
if (it == self->calls.end()) {
return;
}
@ -891,10 +879,12 @@ void CoreAV::audioFrameCallback(ToxAV*, uint32_t friendNum, const int16_t* pcm,
void CoreAV::videoFrameCallback(ToxAV*, uint32_t friendNum, uint16_t w, uint16_t h,
const uint8_t* y, const uint8_t* u, const uint8_t* v,
int32_t ystride, int32_t ustride, int32_t vstride, void*)
int32_t ystride, int32_t ustride, int32_t vstride, void* vSelf)
{
auto it = calls.find(friendNum);
if (it == calls.end()) {
auto self = static_cast<CoreAV*>(vSelf);
auto it = self->calls.find(friendNum);
if (it == self->calls.end()) {
return;
}

View File

@ -132,9 +132,19 @@ private:
std::unique_ptr<QThread> coreavThread;
QTimer* iterateTimer = nullptr;
using ToxFriendCallPtr = std::unique_ptr<ToxFriendCall>;
static std::map<uint32_t, ToxFriendCallPtr> calls;
/**
* @brief Maps friend IDs to ToxFriendCall.
* @note Need to use STL container here, because Qt containers need a copy constructor.
*/
std::map<uint32_t, ToxFriendCallPtr> calls;
using ToxGroupCallPtr = std::unique_ptr<ToxGroupCall>;
static std::map<int, ToxGroupCallPtr> groupCalls;
/**
* @brief Maps group IDs to ToxGroupCalls.
* @note Need to use STL container here, because Qt containers need a copy constructor.
*/
std::map<int, ToxGroupCallPtr> groupCalls;
std::atomic_flag threadSwitchLock;
};