Crash fix on all asynchronous operations. Make alive connections, fix destructor calls.

This commit is contained in:
Julien Wadel 2025-01-22 20:21:13 +01:00
parent 2e08bfe507
commit 1c1bd91080
29 changed files with 80 additions and 98 deletions

View file

@ -296,8 +296,7 @@ App::~App() {
}
void App::setSelf(QSharedPointer<App>(me)) {
mCoreModelConnection = QSharedPointer<SafeConnection<App, CoreModel>>(
new SafeConnection<App, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<App, CoreModel>::create(me, CoreModel::getInstance());
mCoreModelConnection->makeConnectToModel(&CoreModel::callCreated,
[this](const std::shared_ptr<linphone::Call> &call) {
if (call->getDir() == linphone::Call::Dir::Incoming) return;
@ -355,8 +354,7 @@ void App::setSelf(QSharedPointer<App>(me)) {
mCoreModelConnection->invokeToCore([this, state] { setCoreStarted(state == linphone::GlobalState::On); });
});
//---------------------------------------------------------------------------------------------
mCliModelConnection = QSharedPointer<SafeConnection<App, CliModel>>(
new SafeConnection<App, CliModel>(me, CliModel::getInstance()), &QObject::deleteLater);
mCliModelConnection = SafeConnection<App, CliModel>::create(me, CliModel::getInstance());
mCliModelConnection->makeConnectToCore(&App::receivedMessage, [this](int, const QByteArray &byteArray) {
QString command(byteArray);
if (command.isEmpty()) {

View file

@ -141,8 +141,7 @@ AccountCore::AccountCore(const AccountCore &accountCore) {
}
void AccountCore::setSelf(QSharedPointer<AccountCore> me) {
mAccountModelConnection = QSharedPointer<SafeConnection<AccountCore, AccountModel>>(
new SafeConnection<AccountCore, AccountModel>(me, mAccountModel));
mAccountModelConnection = SafeConnection<AccountCore, AccountModel>::create(me, mAccountModel);
mAccountModelConnection->makeConnectToModel(
&AccountModel::registrationStateChanged, [this](const std::shared_ptr<linphone::Account> &account,
linphone::RegistrationState state, const std::string &message) {
@ -237,8 +236,7 @@ void AccountCore::setSelf(QSharedPointer<AccountCore> me) {
mAccountModelConnection->makeConnectToCore(&AccountCore::lRefreshNotifications, [this]() {
mAccountModelConnection->invokeToModel([this]() { mAccountModel->refreshUnreadNotifications(); });
});
mCoreModelConnection = QSharedPointer<SafeConnection<AccountCore, CoreModel>>(
new SafeConnection<AccountCore, CoreModel>(me, CoreModel::getInstance()));
mCoreModelConnection = SafeConnection<AccountCore, CoreModel>::create(me, CoreModel::getInstance());
mAccountModelConnection->makeConnectToCore(&AccountCore::unreadCallNotificationsChanged, [this]() {
mAccountModelConnection->invokeToModel([this]() { CoreModel::getInstance()->unreadNotificationsChanged(); });
});

View file

@ -126,8 +126,7 @@ void AccountDeviceList::deleteDevice(AccountDeviceGui *deviceGui) {
void AccountDeviceList::setSelf(QSharedPointer<AccountDeviceList> me) {
if (mCoreModelConnection) mCoreModelConnection->disconnect();
mCoreModelConnection = QSharedPointer<SafeConnection<AccountDeviceList, CoreModel>>(
new SafeConnection<AccountDeviceList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<AccountDeviceList, CoreModel>::create(me, CoreModel::getInstance());
mCoreModelConnection->invokeToModel([=] {
auto core = CoreModel::getInstance()->getCore();
auto ams = core->createAccountManagerServices();
@ -136,10 +135,8 @@ void AccountDeviceList::setSelf(QSharedPointer<AccountDeviceList> me) {
mAccountManagerServicesModel = amsModel;
if (mAccountManagerServicesModelConnection) mAccountManagerServicesModelConnection->disconnect();
mAccountManagerServicesModelConnection =
QSharedPointer<SafeConnection<AccountDeviceList, AccountManagerServicesModel>>(
new SafeConnection<AccountDeviceList, AccountManagerServicesModel>(me,
mAccountManagerServicesModel),
&QObject::deleteLater);
SafeConnection<AccountDeviceList, AccountManagerServicesModel>::create(me,
mAccountManagerServicesModel);
mAccountManagerServicesModelConnection->makeConnectToModel(
&AccountManagerServicesModel::requestSuccessfull,
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,

View file

@ -47,8 +47,7 @@ AccountList::~AccountList() {
}
void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection = QSharedPointer<SafeConnection<AccountList, CoreModel>>(
new SafeConnection<AccountList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<AccountList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&AccountList::lUpdate, [this](bool isInitialization) {
mModelConnection->invokeToModel([this, isInitialization]() {

View file

@ -72,8 +72,7 @@ void CarddavCore::remove() {
}
void CarddavCore::setSelf(QSharedPointer<CarddavCore> me) {
mCarddavModelConnection = QSharedPointer<SafeConnection<CarddavCore, CarddavModel>>(
new SafeConnection<CarddavCore, CarddavModel>(me, mCarddavModel), &QObject::deleteLater);
mCarddavModelConnection = SafeConnection<CarddavCore, CarddavModel>::create(me, mCarddavModel);
mCarddavModelConnection->makeConnectToModel(&CarddavModel::saved, [this](bool success) {
mCarddavModelConnection->invokeToCore([this, success]() { emit saved(success); });
});

View file

@ -53,8 +53,7 @@ CarddavList::~CarddavList() {
}
void CarddavList::setSelf(QSharedPointer<CarddavList> me) {
mModelConnection = QSharedPointer<SafeConnection<CarddavList, CoreModel>>(
new SafeConnection<CarddavList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<CarddavList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&CarddavList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {
mustBeInLinphoneThread(getClassName());

View file

@ -70,8 +70,7 @@ bool LdapCore::isValid() {
}
void LdapCore::setSelf(QSharedPointer<LdapCore> me) {
mLdapModelConnection = QSharedPointer<SafeConnection<LdapCore, LdapModel>>(
new SafeConnection<LdapCore, LdapModel>(me, mLdapModel), &QObject::deleteLater);
mLdapModelConnection = SafeConnection<LdapCore, LdapModel>::create(me, mLdapModel);
DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, QString, serverUrl, ServerUrl)
DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, QString, bindDn, BindDn)

View file

@ -52,8 +52,7 @@ LdapList::~LdapList() {
}
void LdapList::setSelf(QSharedPointer<LdapList> me) {
mModelConnection = QSharedPointer<SafeConnection<LdapList, CoreModel>>(
new SafeConnection<LdapList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<LdapList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&LdapList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {
QList<QSharedPointer<LdapCore>> *ldaps = new QList<QSharedPointer<LdapCore>>();

View file

@ -76,13 +76,10 @@ CallHistoryCore::~CallHistoryCore() {
}
void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) {
mHistoryModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>>(
new SafeConnection<CallHistoryCore, CallHistoryModel>(me, mCallHistoryModel), &QObject::deleteLater);
mCoreModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>>(
new SafeConnection<CallHistoryCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mHistoryModelConnection = SafeConnection<CallHistoryCore, CallHistoryModel>::create(me, mCallHistoryModel);
mCoreModelConnection = SafeConnection<CallHistoryCore, CoreModel>::create(me, CoreModel::getInstance());
if (mFriendModel) {
mFriendModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, FriendModel>>(
new SafeConnection<CallHistoryCore, FriendModel>(me, mFriendModel), &QObject::deleteLater);
mFriendModelConnection = SafeConnection<CallHistoryCore, FriendModel>::create(me, mFriendModel);
mFriendModelConnection->makeConnectToModel(&FriendModel::fullNameChanged, [this]() {
auto fullName = mFriendModel->getFullName();
mCoreModelConnection->invokeToCore([this, fullName]() {
@ -108,8 +105,7 @@ void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) {
mCoreModelConnection->invokeToCore([this, friendModel, displayName]() {
mFriendModel = friendModel;
auto me = mCoreModelConnection->mCore.mQData; // Locked from previous call.
mFriendModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, FriendModel>>(
new SafeConnection<CallHistoryCore, FriendModel>(me, mFriendModel), &QObject::deleteLater);
mFriendModelConnection = SafeConnection<CallHistoryCore, FriendModel>::create(me, mFriendModel);
mFriendModelConnection->makeConnectToModel(&FriendModel::fullNameChanged, [this]() {
auto fullName = mFriendModel->getFullName();
mCoreModelConnection->invokeToCore([this, fullName]() {

View file

@ -53,8 +53,7 @@ CallHistoryList::~CallHistoryList() {
}
void CallHistoryList::setSelf(QSharedPointer<CallHistoryList> me) {
mModelConnection = QSharedPointer<SafeConnection<CallHistoryList, CoreModel>>(
new SafeConnection<CallHistoryList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<CallHistoryList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&CallHistoryList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {

View file

@ -183,8 +183,7 @@ CallCore::~CallCore() {
}
void CallCore::setSelf(QSharedPointer<CallCore> me) {
mCallModelConnection = QSharedPointer<SafeConnection<CallCore, CallModel>>(
new SafeConnection<CallCore, CallModel>(me, mCallModel), &QObject::deleteLater);
mCallModelConnection = SafeConnection<CallCore, CallModel>::create(me, mCallModel);
mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneMuted, [this](bool isMuted) {
mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setMicrophoneMuted(isMuted); });
});
@ -783,8 +782,7 @@ void CallCore::findRemoteLdapFriend(QSharedPointer<CallCore> me) {
linphoneSearch->setLimitedSearch(true);
mLdapMagicSearchModel = Utils::makeQObject_ptr<MagicSearchModel>(linphoneSearch);
mLdapMagicSearchModel->setSelf(mLdapMagicSearchModel);
mLdapMagicSearchModelConnection = QSharedPointer<SafeConnection<CallCore, MagicSearchModel>>(
new SafeConnection<CallCore, MagicSearchModel>(me, mLdapMagicSearchModel), &QObject::deleteLater);
mLdapMagicSearchModelConnection = SafeConnection<CallCore, MagicSearchModel>::create(me, mLdapMagicSearchModel);
mLdapMagicSearchModelConnection->makeConnectToModel(
&MagicSearchModel::searchResultsReceived,
[this, remoteAdress = mRemoteAddress](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {

View file

@ -53,8 +53,7 @@ CallList::~CallList() {
}
void CallList::setSelf(QSharedPointer<CallList> me) {
mModelConnection = QSharedPointer<SafeConnection<CallList, CoreModel>>(
new SafeConnection<CallList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<CallList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&CallList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {

View file

@ -56,8 +56,7 @@ ConferenceCore::~ConferenceCore() {
}
void ConferenceCore::setSelf(QSharedPointer<ConferenceCore> me) {
mConferenceModelConnection = QSharedPointer<SafeConnection<ConferenceCore, ConferenceModel>>(
new SafeConnection<ConferenceCore, ConferenceModel>(me, mConferenceModel), &QObject::deleteLater);
mConferenceModelConnection = SafeConnection<ConferenceCore, ConferenceModel>::create(me, mConferenceModel);
mConferenceModelConnection->makeConnectToModel(
&ConferenceModel::activeSpeakerParticipantDevice,
[this](const std::shared_ptr<linphone::ParticipantDevice> &participantDevice) {

View file

@ -156,9 +156,8 @@ void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
if (me) {
if (mConferenceInfoModel) {
mConfInfoModelConnection = nullptr;
mConfInfoModelConnection = QSharedPointer<SafeConnection<ConferenceInfoCore, ConferenceInfoModel>>(
new SafeConnection<ConferenceInfoCore, ConferenceInfoModel>(me, mConferenceInfoModel),
&QObject::deleteLater);
mConfInfoModelConnection =
SafeConnection<ConferenceInfoCore, ConferenceInfoModel>::create(me, mConferenceInfoModel);
mConfInfoModelConnection->makeConnectToModel(&ConferenceInfoModel::dateTimeChanged,
[this](const QDateTime &date) {
@ -222,8 +221,7 @@ void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
[this](const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {});
} else { // Create
mCoreModelConnection = QSharedPointer<SafeConnection<ConferenceInfoCore, CoreModel>>(
new SafeConnection<ConferenceInfoCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<ConferenceInfoCore, CoreModel>::create(me, CoreModel::getInstance());
}
}
}

View file

@ -56,8 +56,7 @@ ConferenceInfoList::~ConferenceInfoList() {
}
void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
mCoreModelConnection = QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>>(
new SafeConnection<ConferenceInfoList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<ConferenceInfoList, CoreModel>::create(me, CoreModel::getInstance());
mCoreModelConnection->makeConnectToCore(&ConferenceInfoList::lUpdate, [this](bool isInitialization) {
mCoreModelConnection->invokeToModel([this, isInitialization]() {

View file

@ -123,8 +123,7 @@ void FriendCore::setSelf(SafeSharedPointer<FriendCore> me) {
void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
if (me) {
if (mFriendModel) {
mFriendModelConnection = QSharedPointer<SafeConnection<FriendCore, FriendModel>>(
new SafeConnection<FriendCore, FriendModel>(me, mFriendModel), &QObject::deleteLater);
mFriendModelConnection = SafeConnection<FriendCore, FriendModel>::create(me, mFriendModel);
mFriendModelConnection->makeConnectToModel(&FriendModel::updated, [this]() {
mFriendModelConnection->invokeToCore([this]() { emit friendUpdated(); });
});
@ -199,8 +198,7 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
mFriendModelConnection->invokeToModel([this, starred]() { mFriendModel->setStarred(starred); });
});
if (!mCoreModelConnection) {
mCoreModelConnection = QSharedPointer<SafeConnection<FriendCore, CoreModel>>(
new SafeConnection<FriendCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<FriendCore, CoreModel>::create(me, CoreModel::getInstance());
}
mCoreModelConnection->makeConnectToModel(
&CoreModel::callStateChanged,
@ -227,8 +225,7 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
});
} else { // Create
mCoreModelConnection = QSharedPointer<SafeConnection<FriendCore, CoreModel>>(
new SafeConnection<FriendCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<FriendCore, CoreModel>::create(me, CoreModel::getInstance());
}
}
}

View file

@ -68,8 +68,7 @@ ParticipantCore::~ParticipantCore() {
}
void ParticipantCore::setSelf(QSharedPointer<ParticipantCore> me) {
mParticipantConnection = QSharedPointer<SafeConnection<ParticipantCore, ParticipantModel>>(
new SafeConnection<ParticipantCore, ParticipantModel>(me, mParticipantModel), &QObject::deleteLater);
mParticipantConnection = SafeConnection<ParticipantCore, ParticipantModel>::create(me, mParticipantModel);
mParticipantConnection->makeConnectToCore(&ParticipantCore::lStartInvitation, [this](const int &secs) {
QTimer::singleShot(secs * 1000, this, &ParticipantCore::onEndOfInvitation);
});

View file

@ -68,9 +68,8 @@ ParticipantDeviceCore::~ParticipantDeviceCore() {
}
void ParticipantDeviceCore::setSelf(QSharedPointer<ParticipantDeviceCore> me) {
mParticipantDeviceModelConnection = QSharedPointer<SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>>(
new SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>(me, mParticipantDeviceModel),
&QObject::deleteLater);
mParticipantDeviceModelConnection =
SafeConnection<ParticipantDeviceCore, ParticipantDeviceModel>::create(me, mParticipantDeviceModel);
mParticipantDeviceModelConnection->makeConnectToModel(
&ParticipantDeviceModel::isSpeakingChanged, [this](bool speaking) {
mParticipantDeviceModelConnection->invokeToCore([this, speaking] { setIsSpeaking(speaking); });

View file

@ -119,8 +119,7 @@ void ParticipantDeviceList::setConferenceModel(const std::shared_ptr<ConferenceM
void ParticipantDeviceList::setSelf(QSharedPointer<ParticipantDeviceList> me) {
if (mConferenceModelConnection) mConferenceModelConnection->disconnect();
mConferenceModelConnection = QSharedPointer<SafeConnection<ParticipantDeviceList, ConferenceModel>>(
new SafeConnection<ParticipantDeviceList, ConferenceModel>(me, mConferenceModel), &QObject::deleteLater);
mConferenceModelConnection = SafeConnection<ParticipantDeviceList, ConferenceModel>::create(me, mConferenceModel);
if (mConferenceModel) {
mConferenceModelConnection->makeConnectToModel(
&ConferenceModel::participantDeviceAdded,

View file

@ -52,8 +52,7 @@ ParticipantList::~ParticipantList() {
void ParticipantList::setSelf(QSharedPointer<ParticipantList> me) {
if (mConferenceModelConnection) mConferenceModelConnection->disconnect();
mConferenceModelConnection = QSharedPointer<SafeConnection<ParticipantList, ConferenceModel>>(
new SafeConnection<ParticipantList, ConferenceModel>(me, mConferenceModel), &QObject::deleteLater);
mConferenceModelConnection = SafeConnection<ParticipantList, ConferenceModel>::create(me, mConferenceModel);
if (mConferenceModel) {
mConferenceModelConnection->makeConnectToCore(&ParticipantList::lUpdateParticipants, [this] {
mConferenceModelConnection->invokeToModel([this]() {

View file

@ -67,10 +67,8 @@ DownloadablePayloadTypeCore::~DownloadablePayloadTypeCore() {
void DownloadablePayloadTypeCore::setSelf(QSharedPointer<DownloadablePayloadTypeCore> me) {
mDownloadablePayloadTypeModelConnection =
QSharedPointer<SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>>(
new SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>(
me, mDownloadablePayloadTypeModel),
&QObject::deleteLater);
SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>::create(
me, mDownloadablePayloadTypeModel);
mDownloadablePayloadTypeModelConnection->makeConnectToCore(
&DownloadablePayloadTypeCore::extractSuccess, [this](QString filePath) {

View file

@ -50,8 +50,7 @@ PayloadTypeCore::~PayloadTypeCore() {
}
void PayloadTypeCore::setSelf(QSharedPointer<PayloadTypeCore> me) {
mPayloadTypeModelConnection = QSharedPointer<SafeConnection<PayloadTypeCore, PayloadTypeModel>>(
new SafeConnection<PayloadTypeCore, PayloadTypeModel>(me, mPayloadTypeModel), &QObject::deleteLater);
mPayloadTypeModelConnection = SafeConnection<PayloadTypeCore, PayloadTypeModel>::create(me, mPayloadTypeModel);
DEFINE_CORE_GETSET_CONNECT(mPayloadTypeModelConnection, PayloadTypeCore, PayloadTypeModel, mPayloadTypeModel, bool,
enabled, Enabled)
}

View file

@ -50,8 +50,7 @@ PayloadTypeList::~PayloadTypeList() {
}
void PayloadTypeList::setSelf(QSharedPointer<PayloadTypeList> me) {
mModelConnection = QSharedPointer<SafeConnection<PayloadTypeList, CoreModel>>(
new SafeConnection<PayloadTypeList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection = SafeConnection<PayloadTypeList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&PayloadTypeList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {
QList<QSharedPointer<PayloadTypeCore>> *payloadTypes = new QList<QSharedPointer<PayloadTypeCore>>();

View file

@ -50,8 +50,7 @@ MagicSearchList::~MagicSearchList() {
}
void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
mCoreModelConnection = QSharedPointer<SafeConnection<MagicSearchList, CoreModel>>(
new SafeConnection<MagicSearchList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection = SafeConnection<MagicSearchList, CoreModel>::create(me, CoreModel::getInstance());
mCoreModelConnection->makeConnectToModel(
&CoreModel::friendCreated, [this](const std::shared_ptr<linphone::Friend> &f) {
auto friendCore = FriendCore::create(f);
@ -74,9 +73,8 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
mCoreModelConnection->invokeToCore([this, magicSearch] {
mMagicSearch = magicSearch;
mMagicSearch->setSelf(mMagicSearch);
mModelConnection = QSharedPointer<SafeConnection<MagicSearchList, MagicSearchModel>>(
new SafeConnection<MagicSearchList, MagicSearchModel>(mCoreModelConnection->mCore.mQData, mMagicSearch),
&QObject::deleteLater);
mModelConnection = SafeConnection<MagicSearchList, MagicSearchModel>::create(
mCoreModelConnection->mCore.mQData, mMagicSearch);
mModelConnection->makeConnectToCore(
&MagicSearchList::lSearch,
[this](QString filter, int sourceFlags, LinphoneEnums::MagicSearchAggregation aggregationFlag,

View file

@ -190,8 +190,7 @@ SettingsCore::~SettingsCore() {
void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
mustBeInLinphoneThread(getClassName());
mSettingsModelConnection = QSharedPointer<SafeConnection<SettingsCore, SettingsModel>>(
new SafeConnection<SettingsCore, SettingsModel>(me, SettingsModel::getInstance()), &QObject::deleteLater);
mSettingsModelConnection = SafeConnection<SettingsCore, SettingsModel>::create(me, SettingsModel::getInstance());
// VFS
mSettingsModelConnection->makeConnectToModel(&SettingsModel::vfsEnabledChanged, [this](const bool enabled) {
@ -388,8 +387,7 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
DEFINE_CORE_GET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QVariantList,
shortcuts, Shortcuts)
auto coreModelConnection = QSharedPointer<SafeConnection<SettingsCore, CoreModel>>(
new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
auto coreModelConnection = SafeConnection<SettingsCore, CoreModel>::create(me, CoreModel::getInstance());
coreModelConnection->makeConnectToModel(
&CoreModel::logCollectionUploadStateChanged, [this](auto core, auto state, auto info) {

View file

@ -48,9 +48,8 @@ VideoSourceDescriptorCore::~VideoSourceDescriptorCore() {
}
void VideoSourceDescriptorCore::setSelf(QSharedPointer<VideoSourceDescriptorCore> me) {
mVideoDescModelConnection = QSharedPointer<SafeConnection<VideoSourceDescriptorCore, VideoSourceDescriptorModel>>(
new SafeConnection<VideoSourceDescriptorCore, VideoSourceDescriptorModel>(me, mVideoDescModel),
&QObject::deleteLater);
mVideoDescModelConnection =
SafeConnection<VideoSourceDescriptorCore, VideoSourceDescriptorModel>::create(me, mVideoDescModel);
mVideoDescModelConnection->makeConnectToCore(&VideoSourceDescriptorCore::lSetWindowId, [this](quint64 id) {
mVideoDescModelConnection->invokeToModel([this, id]() { mVideoDescModel->setScreenSharingWindow((void *)id); });
});

View file

@ -37,8 +37,7 @@ VariantObject::VariantObject(QString name, QVariant defaultValue, QObject *paren
App::getInstance()->mEngine->setObjectOwnership(mCoreObject.get(), QQmlEngine::CppOwnership);
App::getInstance()->mEngine->setObjectOwnership(mModelObject.get(), QQmlEngine::CppOwnership);
mConnection = QSharedPointer<SafeConnection<SafeObject, SafeObject>>(
new SafeConnection<SafeObject, SafeObject>(mCoreObject, mModelObject), &QObject::deleteLater);
mConnection = SafeConnection<SafeObject, SafeObject>::create(mCoreObject, mModelObject);
// Note: do not use member because 'this' is managed by GUI and can be deleted. Objects scope should have the same
// as connections so it should be fine to use the object directly.

View file

@ -372,11 +372,10 @@ VariantObject *Utils::findAvatarByAddress(const QString &address) {
VariantObject *Utils::findFriendByAddress(const QString &address) {
VariantObject *data = new VariantObject("findFriendByAddress");
if (!data) return nullptr;
data->makeRequest([data, address]() {
data->makeRequest([address]() {
auto linFriend = ToolModel::findFriendByAddress(address);
if (!linFriend) return QVariant();
auto friendCore = FriendCore::create(linFriend);
connect(friendCore.get(), &FriendCore::removed, data, &VariantObject::invokeRequestValue);
return QVariant::fromValue(new FriendGui(friendCore));
});
// Rebuild friend if needed
@ -384,6 +383,7 @@ VariantObject *Utils::findFriendByAddress(const QString &address) {
if (f->getAddress()->weakEqual(ToolModel::interpretUrl(address))) data->invokeRequestValue();
};
data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendCreated, updateValue); // New Friend
data->makeUpdateCond(CoreModel::getInstance().get(), &CoreModel::friendRemoved, updateValue); // New Friend
data->requestValue();
return data;
}

View file

@ -64,8 +64,8 @@
template <class A, class B>
class SafeConnection : public QObject {
public:
// SafeConnection(SafeSharedPointer<QObject> a, SafeSharedPointer<QObject> b);
// Use create functions.
protected:
SafeConnection(QSharedPointer<A> a, std::shared_ptr<B> b)
: mCore(a), mModel(b), mCoreObject(a.get()), mModelObject(b.get()) {
}
@ -84,9 +84,28 @@ public:
});
mLocker.unlock();
}
void setSelf(QSharedPointer<SafeConnection> me) {
mSelf = me;
}
public:
static QSharedPointer<SafeConnection> create(QSharedPointer<A> a, std::shared_ptr<B> b) {
QSharedPointer<SafeConnection> me =
QSharedPointer<SafeConnection<A, B>>(new SafeConnection<A, B>(a, b), &QObject::deleteLater);
me->setSelf(me);
return me;
}
static QSharedPointer<SafeConnection> create(QSharedPointer<A> a, QSharedPointer<B> b) {
QSharedPointer<SafeConnection> me =
QSharedPointer<SafeConnection<A, B>>(new SafeConnection<A, B>(a, b), &QObject::deleteLater);
me->setSelf(me);
return me;
}
SafeSharedPointer<A> mCore;
SafeSharedPointer<B> mModel;
QMutex mLocker;
QWeakPointer<SafeConnection> mSelf;
template <typename Func1, typename Func2>
inline QMetaObject::Connection makeConnectToModel(Func1 signal, Func2 slot) {
@ -112,9 +131,9 @@ public:
template <typename Func, typename... Args>
void invokeToModel(Func &&callable, Args &&...args) {
if (!tryLock()) return;
auto model = mModel.get();
QMetaObject::invokeMethod(model, [&, model, callable, args...]() { // Is async
QMetaObject::invokeMethod(model, callable, args...); // Is Sync
auto connection = mSelf.lock();
QMetaObject::invokeMethod(mModel.get(), [&, connection, callable, args...]() { // Is async
QMetaObject::invokeMethod(mModel.get(), callable, args...); // Is Sync
unlock();
});
}
@ -123,23 +142,27 @@ public:
template <typename Func, typename... Args>
void invokeToCore(Func &&callable, Args &&...args) {
if (!tryLock()) return;
QMetaObject::invokeMethod(mCore.get(), [&, callable, args...]() { // Is async
QMetaObject::invokeMethod(mCore.get(), callable, args...); // Is Sync
auto connection = mSelf.lock();
QMetaObject::invokeMethod(mCore.get(), [&, connection, callable, args...]() { // Is async
QMetaObject::invokeMethod(mCore.get(), callable, args...); // Is Sync
unlock();
});
}
bool tryLock() {
mLocker.lock();
if (!mCore.lock() || !mModel.lock()) { // Direct locking
mCore.reset();
mModel.reset();
auto coreLocked = mCore.lock();
auto modelLocked = mModel.lock();
if (!coreLocked || !modelLocked) {
if (coreLocked) mCore.unlock();
if (modelLocked) mModel.unlock();
mLocker.unlock();
return false;
}
mLocker.unlock();
return true;
}
void unlock() {
mLocker.lock();
mCore.unlock();