Destroy all tgcalls instances before quit.

This commit is contained in:
John Preston 2021-05-17 16:19:02 +04:00
parent f4ae7ecbe7
commit b905a18161
4 changed files with 54 additions and 3 deletions

View File

@ -73,6 +73,7 @@ public:
void groupCallPlaySound(GroupCallSound sound) override;
auto groupCallGetVideoCapture(const QString &deviceId)
-> std::shared_ptr<tgcalls::VideoCaptureInterface> override;
FnMut<void()> groupCallAddAsyncWaiter() override;
private:
const not_null<Instance*> _instance;
@ -161,13 +162,24 @@ auto Instance::Delegate::groupCallGetVideoCapture(const QString &deviceId)
return _instance->getVideoCapture(deviceId);
}
FnMut<void()> Instance::Delegate::groupCallAddAsyncWaiter() {
return _instance->addAsyncWaiter();
}
Instance::Instance()
: _delegate(std::make_unique<Delegate>(this))
, _cachedDhConfig(std::make_unique<DhConfig>())
, _chooseJoinAs(std::make_unique<Group::ChooseJoinAsProcess>()) {
}
Instance::~Instance() = default;
Instance::~Instance() {
destroyCurrentCall();
while (!_asyncWaiters.empty()) {
_asyncWaiters.front()->acquire();
_asyncWaiters.erase(_asyncWaiters.begin());
}
}
void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
if (activateCurrentCall()) {
@ -426,6 +438,26 @@ void Instance::setCurrentAudioDevice(bool input, const QString &deviceId) {
}
}
FnMut<void()> Instance::addAsyncWaiter() {
auto semaphore = std::make_unique<crl::semaphore>();
const auto raw = semaphore.get();
const auto weak = base::make_weak(this);
_asyncWaiters.emplace(std::move(semaphore));
return [raw, weak] {
raw->release();
crl::on_main(weak, [raw, weak] {
auto &waiters = weak->_asyncWaiters;
auto wrapped = std::unique_ptr<crl::semaphore>(raw);
const auto i = waiters.find(wrapped);
wrapped.release();
if (i != end(waiters)) {
waiters.erase(i);
}
});
};
}
bool Instance::isQuitPrevent() {
if (!_currentCall || _currentCall->isIncomingWaiting()) {
return false;

View File

@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/sender.h"
namespace crl {
class semaphore;
} // namespace crl
namespace Platform {
enum class PermissionType;
} // namespace Platform
@ -77,6 +81,8 @@ public:
void setCurrentAudioDevice(bool input, const QString &deviceId);
[[nodiscard]] FnMut<void()> addAsyncWaiter();
[[nodiscard]] bool isQuitPrevent();
private:
@ -132,6 +138,8 @@ private:
const std::unique_ptr<Group::ChooseJoinAsProcess> _chooseJoinAs;
base::flat_set<std::unique_ptr<crl::semaphore>> _asyncWaiters;
};
} // namespace Calls

View File

@ -2504,9 +2504,14 @@ void GroupCall::destroyController() {
if (_instance) {
DEBUG_LOG(("Call Info: Destroying call controller.."));
invalidate_weak_ptrs(&_instanceGuard);
crl::async([instance = base::take(_instance)]() mutable {
crl::async([
instance = base::take(_instance),
done = _delegate->groupCallAddAsyncWaiter()
]() mutable {
instance = nullptr;
DEBUG_LOG(("Call Info: Call controller destroyed."));
done();
});
}
}
@ -2515,9 +2520,13 @@ void GroupCall::destroyScreencast() {
if (_screenInstance) {
DEBUG_LOG(("Call Info: Destroying call screen controller.."));
invalidate_weak_ptrs(&_screenInstanceGuard);
crl::async([instance = base::take(_screenInstance)]() mutable {
crl::async([
instance = base::take(_screenInstance),
done = _delegate->groupCallAddAsyncWaiter()
]() mutable {
instance = nullptr;
DEBUG_LOG(("Call Info: Call screen controller destroyed."));
done();
});
}
}

View File

@ -167,6 +167,8 @@ public:
virtual void groupCallPlaySound(GroupCallSound sound) = 0;
virtual auto groupCallGetVideoCapture(const QString &deviceId)
-> std::shared_ptr<tgcalls::VideoCaptureInterface> = 0;
[[nodiscard]] virtual FnMut<void()> groupCallAddAsyncWaiter() = 0;
};
using GlobalShortcutManager = base::GlobalShortcutManager;