From d83bcfcf5ca5c4293aecd83607a629c7de16d066 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> Date: Mon, 13 Apr 2015 17:45:58 -0400 Subject: [PATCH] call: Handle daemon/libringclient IPC race condition Refs #69138 (cherry picked from commit 19027630ceacdbe542d004b999a2bd790aaab06e) --- src/call.cpp | 14 ++++++++++++++ src/callmodel.cpp | 21 +++++++++++++++++++-- src/private/accountmodel_p.h | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/call.cpp b/src/call.cpp index 8d35d0d1..b8a7cff1 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -369,6 +369,13 @@ Call* CallPrivate::buildIncomingCall(const QString& callId) const QString from = details[ CallPrivate::DetailsMapFields::PEER_NUMBER ]; const QString account = details[ CallPrivate::DetailsMapFields::ACCOUNT_ID ]; const QString peerName = details[ CallPrivate::DetailsMapFields::PEER_NAME ]; + + //It may be possible that the call has already been invalidated + if (account.isEmpty()) { + qWarning() << "Building incoming call" << callId << "failed, it may already have been destroyed by the daemon"; + return nullptr; + } + Account* acc = AccountModel::instance()->getById(account.toLatin1()); ContactMethod* nb = PhoneDirectoryModel::instance()->getNumber(from,acc); Call* call = new Call(Call::State::INCOMING, peerName, nb, acc); @@ -395,6 +402,13 @@ Call* CallPrivate::buildRingingCall(const QString & callId) const QString from = details[ CallPrivate::DetailsMapFields::PEER_NUMBER ]; const QString account = details[ CallPrivate::DetailsMapFields::ACCOUNT_ID ]; const QString peerName = details[ CallPrivate::DetailsMapFields::PEER_NAME ]; + + //It may be possible that the call has already been invalidated + if (account.isEmpty()) { + qWarning() << "Building ringing call" << callId << "failed, it may already have been destroyed by the daemon"; + return nullptr; + } + Account* acc = AccountModel::instance()->getById(account.toLatin1()); ContactMethod* nb = PhoneDirectoryModel::instance()->getNumber(from,acc); Call* call = new Call(Call::State::RINGING, peerName, nb, acc); diff --git a/src/callmodel.cpp b/src/callmodel.cpp index c1c79297..1117d9e9 100644 --- a/src/callmodel.cpp +++ b/src/callmodel.cpp @@ -443,6 +443,11 @@ Call* CallModel::dialingCall(const QString& peerName, Account* account) Call* CallModelPrivate::addIncomingCall(const QString& callId) { Call* call = addCall2(CallPrivate::buildIncomingCall(callId)); + + //The call can already have been invalidated by the daemon, then do nothing + if (!call) + return nullptr; + //Call without account is not possible if (call->account()) { if (call->account()->isAutoAnswer()) { @@ -459,7 +464,12 @@ Call* CallModelPrivate::addIncomingCall(const QString& callId) ///Create a ringing call Call* CallModelPrivate::addRingingCall(const QString& callId) { - return addCall2(CallPrivate::buildRingingCall(callId)); + Call* c = CallPrivate::buildRingingCall(callId); + + if (!c) + return nullptr; + + return addCall2(c); } ///Properly remove an internal from the Qt model @@ -1021,6 +1031,10 @@ void CallModelPrivate::slotCallStateChanged(const QString& callID, const QString qDebug() << "Call not found" << callID << "new state" << stateName; if(stateName == CallPrivate::StateChange::RINGING) { call = addRingingCall(callID); + + if (!call) + return; + } else { qDebug() << "Call doesn't exist in this client. Might have been initialized by another client instance before this one started."; @@ -1059,7 +1073,10 @@ void CallModelPrivate::slotIncomingCall(const QString& accountID, const QString& { Q_UNUSED(accountID) qDebug() << "Signal : Incoming Call ! ID = " << callID; - emit q_ptr->incomingCall(addIncomingCall(callID)); + Call* c = addIncomingCall(callID); + + if (c) + emit q_ptr->incomingCall(c); } ///When a new conference is incoming diff --git a/src/private/accountmodel_p.h b/src/private/accountmodel_p.h index dc192b99..a349298a 100644 --- a/src/private/accountmodel_p.h +++ b/src/private/accountmodel_p.h @@ -44,7 +44,7 @@ public: //Helpers static Account::RegistrationState fromDaemonName(const QString& st); - void enabledProtocol(Account::Protocol proto); + void enableProtocol(Account::Protocol proto); //Attributes AccountModel* q_ptr ; -- GitLab