2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-09-05 09:05:14 +00:00

Don't lock whole key creation by a mutex.

This commit is contained in:
John Preston
2019-11-15 16:04:32 +03:00
parent 055b99f5b0
commit be06d68468
12 changed files with 397 additions and 445 deletions

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/dcenter.h"
#include "mtproto/auth_key.h"
#include "base/unixtime.h"
#include "base/openssl_help.h"
#include "core/crash_reports.h"
#include "facades.h"
@@ -63,19 +64,15 @@ ConnectionOptions::ConnectionOptions(
, useTcp(useTcp) {
}
void SessionData::setKey(const AuthKeyPtr &key) {
if (_authKey != key) {
const auto sessionId = rand_value<uint64>();
_authKey = key;
DEBUG_LOG(("MTP Info: new auth key set in SessionData, id %1, setting random server_session %2").arg(key ? key->keyId() : 0).arg(sessionId));
QWriteLocker locker(&_lock);
if (_sessionId != sessionId) {
_sessionId = sessionId;
_messagesSent = 0;
}
_layerInited = false;
void SessionData::setCurrentKeyId(uint64 keyId) {
QWriteLocker locker(&_lock);
if (_keyId == keyId) {
return;
}
_keyId = keyId;
_sessionId = openssl::RandomValue<uint64>();
_messagesSent = 0;
DEBUG_LOG(("MTP Info: new auth key set in SessionData, id %1, setting random server_session %2").arg(_keyId).arg(_sessionId));
}
void SessionData::setKeyForCheck(const AuthKeyPtr &key) {
@@ -83,25 +80,24 @@ void SessionData::setKeyForCheck(const AuthKeyPtr &key) {
}
void SessionData::notifyConnectionInited(const ConnectionOptions &options) {
QWriteLocker locker(&_lock);
if (options.cloudLangCode == _options.cloudLangCode
&& options.systemLangCode == _options.systemLangCode
&& options.langPackName == _options.langPackName
&& options.proxy == _options.proxy
&& !_options.inited) {
_options.inited = true;
locker.unlock();
// #TODO race
const auto current = connectionOptions();
if (current.cloudLangCode == _options.cloudLangCode
&& current.systemLangCode == _options.systemLangCode
&& current.langPackName == _options.langPackName
&& current.proxy == _options.proxy) {
owner()->notifyDcConnectionInited();
}
}
void SessionData::clear(Instance *instance) {
void SessionData::clearForNewKey(not_null<Instance*> instance) {
auto clearCallbacks = std::vector<RPCCallbackClear>();
{
QReadLocker locker1(haveSentMutex()), locker2(toResendMutex()), locker3(haveReceivedMutex()), locker4(wereAckedMutex());
auto receivedResponsesEnd = _receivedResponses.cend();
clearCallbacks.reserve(_haveSent.size() + _wereAcked.size());
QReadLocker locker1(haveSentMutex());
QReadLocker locker2(toResendMutex());
QReadLocker locker3(haveReceivedMutex());
QReadLocker locker4(wereAckedMutex());
clearCallbacks.reserve(_haveSent.size() + _toResend.size() + _wereAcked.size());
for (auto i = _haveSent.cbegin(), e = _haveSent.cend(); i != e; ++i) {
auto requestId = i.value()->requestId;
if (!_receivedResponses.contains(requestId)) {
@@ -147,21 +143,15 @@ Session::Session(
: QObject()
, _instance(instance)
, _shiftedDcId(shiftedDcId)
, _dc(dc)
, _ownedDc(dc ? nullptr : std::make_unique<Dcenter>(shiftedDcId, nullptr))
, _dc(dc ? dc : _ownedDc.get())
, _data(this)
, _timeouter([=] { checkRequestsByTimer(); })
, _sender([=] { needToResumeAndSend(); }) {
_timeouter.callEach(1000);
refreshOptions();
if (_dc) {
if (const auto lock = ReadLockerAttempt(keyMutex())) {
_data.setKey(_dc->getKey());
if (_dc->connectionInited()) {
_data.setConnectionInited();
}
}
connect(_dc, SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC()), Qt::QueuedConnection);
connect(_dc, SIGNAL(connectionWasInited()), this, SLOT(connectionWasInitedForDC()), Qt::QueuedConnection);
if (sharedDc()) {
connect(_dc, SIGNAL(authKeyChanged()), this, SLOT(authKeyChangedForDC()), Qt::QueuedConnection);
}
}
@@ -199,7 +189,7 @@ void Session::refreshOptions() {
const auto useHttp = (proxyType != ProxyData::Type::Mtproto);
const auto useIPv4 = true;
const auto useIPv6 = Global::TryIPv6();
_data.applyConnectionOptions(ConnectionOptions(
_data.setConnectionOptions(ConnectionOptions(
_instance->systemLangCode(),
_instance->cloudLangCode(),
_instance->langPackName(),
@@ -213,10 +203,7 @@ void Session::refreshOptions() {
}
void Session::reInitConnection() {
if (_dc) {
_dc->setConnectionInited(false);
}
_data.setConnectionInited(false);
_dc->setConnectionInited(false);
restart();
}
@@ -315,6 +302,10 @@ void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
MTP_msgs_state_info(MTP_long(msgId), MTP_bytes(data))));
}
bool Session::sharedDc() const {
return (_ownedDc == nullptr);
}
void Session::checkRequestsByTimer() {
QVector<mtpMsgId> resendingIds;
QVector<mtpMsgId> removingIds; // remove very old (10 minutes) containers and resend requests
@@ -555,51 +546,44 @@ void Session::sendPrepared(
sendAnything(msCanWait);
}
QReadWriteLock *Session::keyMutex() const {
return _dc ? _dc->keyMutex() : nullptr;
void Session::authKeyChangedForDC() {
DEBUG_LOG(("AuthKey Info: Session::authKeyCreatedForDC slot, emitting authKeyChanged(), dcWithShift %1").arg(_shiftedDcId));
emit authKeyChanged();
}
void Session::authKeyCreatedForDC() {
Expects(_dc != nullptr);
DEBUG_LOG(("AuthKey Info: Session::authKeyCreatedForDC slot, emitting authKeyCreated(), dcWithShift %1").arg(_shiftedDcId));
_data.setKey(_dc->getKey());
emit authKeyCreated();
bool Session::acquireKeyCreation() {
return _dc->acquireKeyCreation();
}
void Session::notifyKeyCreated(AuthKeyPtr &&key) {
DEBUG_LOG(("AuthKey Info: Session::keyCreated(), setting, dcWithShift %1").arg(_shiftedDcId));
if (_dc) {
_dc->setKey(std::move(key));
} else {
_data.setKey(std::move(key));
emit authKeyCreated();
void Session::releaseKeyCreationOnFail() {
_dc->releaseKeyCreationOnFail();
}
void Session::releaseKeyCreationOnDone(AuthKeyPtr &&key) {
DEBUG_LOG(("AuthKey Info: Session key created, setting, dcWithShift %1").arg(_shiftedDcId));
if (sharedDc()) {
const auto dcId = _dc->id();
const auto instance = _instance;
InvokeQueued(instance, [=] {
instance->setKeyForWrite(dcId, key);
});
}
}
void Session::connectionWasInitedForDC() {
Expects(_dc != nullptr);
DEBUG_LOG(("MTP Info: Session::connectionWasInitedForDC slot, dcWithShift %1").arg(_shiftedDcId));
_data.setConnectionInited();
_dc->releaseKeyCreationOnDone(std::move(key));
}
void Session::notifyDcConnectionInited() {
DEBUG_LOG(("MTP Info: emitting MTProtoDC::connectionWasInited(), dcWithShift %1").arg(_shiftedDcId));
if (_dc) {
_dc->setConnectionInited();
} else {
_data.setConnectionInited();
}
_dc->setConnectionInited();
}
void Session::destroyKey() {
if (const auto key = _data.getKey()) {
DEBUG_LOG(("MTP Info: destroying auth_key for dcWithShift %1").arg(_shiftedDcId));
if (_dc && _dc->getKey() == key) {
_dc->destroyKey();
}
_data.setKey(nullptr);
void Session::destroyCdnKey(uint64 keyId) {
_dc->destroyCdnKey(keyId);
if (sharedDc()) {
const auto dcId = _dc->id();
const auto instance = _instance;
InvokeQueued(instance, [=] {
instance->setKeyForWrite(dcId, nullptr);
});
}
}
@@ -607,6 +591,14 @@ int32 Session::getDcWithShift() const {
return _shiftedDcId;
}
AuthKeyPtr Session::getKey() const {
return _dc->getKey();
}
bool Session::connectionInited() const {
return _dc->connectionInited();
}
void Session::tryToReceive() {
if (_killed) {
DEBUG_LOG(("Session Error: can't receive in a killed session"));