2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-09-02 07:25:46 +00:00

MTP global state moved to MTP::Instance class.

Now there will be ability to start multiple mtproto instances.
This commit is contained in:
John Preston
2017-02-24 20:15:41 +03:00
parent c3b3819d9f
commit dd933cf61c
23 changed files with 1868 additions and 1341 deletions

View File

@@ -19,13 +19,14 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "mtproto/session.h"
#include "mtproto/connection.h"
namespace MTP {
namespace internal {
void SessionData::clear() {
void SessionData::clear(Instance *instance) {
RPCCallbackClears clearCallbacks;
{
QReadLocker locker1(haveSentMutex()), locker2(toResendMutex()), locker3(haveReceivedMutex()), locker4(wereAckedMutex());
@@ -66,42 +67,23 @@ void SessionData::clear() {
QWriteLocker locker(receivedIdsMutex());
receivedIds.clear();
}
clearCallbacksDelayed(clearCallbacks);
instance->clearCallbacksDelayed(clearCallbacks);
}
Session::Session(int32 requestedDcId) : QObject()
, _connection(0)
, _killed(false)
, _needToReceive(false)
, data(this)
, dcWithShift(0)
, dc(0)
, msSendCall(0)
, msWait(0)
, _ping(false) {
if (_killed) {
DEBUG_LOG(("Session Error: can't start a killed session"));
return;
}
if (dcWithShift) {
DEBUG_LOG(("Session Info: Session::start called on already started session"));
return;
}
msSendCall = msWait = 0;
Session::Session(Instance *instance, ShiftedDcId requestedShiftedDcId) : QObject()
, _instance(instance)
, data(this) {
connect(&timeouter, SIGNAL(timeout()), this, SLOT(checkRequestsByTimer()));
timeouter.start(1000);
connect(&sender, SIGNAL(timeout()), this, SLOT(needToResumeAndSend()));
_connection = new Connection();
dcWithShift = _connection->prepare(&data, requestedDcId);
_connection = std::make_unique<Connection>(_instance);
dcWithShift = _connection->prepare(&data, requestedShiftedDcId);
if (!dcWithShift) {
delete _connection;
_connection = 0;
DEBUG_LOG(("Session Info: could not start connection to dc %1").arg(requestedDcId));
_connection.reset();
DEBUG_LOG(("Session Info: could not start connection to dc %1").arg(requestedShiftedDcId));
return;
}
createDcData();
@@ -112,24 +94,33 @@ void Session::createDcData() {
if (dc) {
return;
}
int32 dcId = bareDcId(dcWithShift);
auto dcId = bareDcId(dcWithShift);
auto &dcs = DCMap();
auto dcIndex = dcs.constFind(dcId);
if (dcIndex == dcs.cend()) {
dc = DcenterPtr(new Dcenter(dcId, AuthKeyPtr()));
dcs.insert(dcId, dc);
} else {
dc = dcIndex.value();
}
dc = _instance->getDcById(dcId);
ReadLockerAttempt lock(keyMutex());
data.setKey(lock ? dc->getKey() : AuthKeyPtr());
if (lock && dc->connectionInited()) {
data.setLayerWasInited(true);
}
connect(dc.data(), SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC()), Qt::QueuedConnection);
connect(dc.data(), SIGNAL(layerWasInited(bool)), this, SLOT(layerWasInitedForDC(bool)), Qt::QueuedConnection);
connect(dc.get(), SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC()), Qt::QueuedConnection);
connect(dc.get(), SIGNAL(layerWasInited(bool)), this, SLOT(layerWasInitedForDC(bool)), Qt::QueuedConnection);
}
void Session::registerRequest(mtpRequestId requestId, ShiftedDcId dcWithShift) {
return _instance->registerRequest(requestId, dcWithShift);
}
mtpRequestId Session::storeRequest(mtpRequest &request, const RPCResponseHandler &parser) {
return _instance->storeRequest(request, parser);
}
mtpRequest Session::getRequest(mtpRequestId requestId) {
return _instance->getRequest(requestId);
}
bool Session::rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err) { // return true if need to clean request data
return _instance->rpcErrorOccured(requestId, onFail, err);
}
void Session::restart() {
@@ -148,7 +139,7 @@ void Session::stop() {
DEBUG_LOG(("Session Info: stopping session dcWithShift %1").arg(dcWithShift));
if (_connection) {
_connection->kill();
_connection = 0;
_instance->queueQuittingConnection(std::move(_connection));
}
}
@@ -202,12 +193,9 @@ void Session::needToResumeAndSend() {
}
if (!_connection) {
DEBUG_LOG(("Session Info: resuming session dcWithShift %1").arg(dcWithShift));
DcenterMap &dcs(DCMap());
_connection = new Connection();
_connection = std::make_unique<Connection>(_instance);
if (!_connection->prepare(&data, dcWithShift)) {
delete _connection;
_connection = 0;
_connection.reset();
DEBUG_LOG(("Session Info: could not start connection to dcWithShift %1").arg(dcWithShift));
dcWithShift = 0;
return;
@@ -298,16 +286,16 @@ void Session::checkRequestsByTimer() {
}
}
}
clearCallbacksDelayed(clearCallbacks);
_instance->clearCallbacksDelayed(clearCallbacks);
}
}
void Session::onConnectionStateChange(qint32 newState) {
onStateChange(dcWithShift, newState);
_instance->onStateChange(dcWithShift, newState);
}
void Session::onResetDone() {
onSessionReset(dcWithShift);
_instance->onSessionReset(dcWithShift);
}
void Session::cancel(mtpRequestId requestId, mtpMsgId msgId) {
@@ -473,9 +461,9 @@ void Session::authKeyCreatedForDC() {
emit authKeyCreated();
}
void Session::notifyKeyCreated(const AuthKeyPtr &key) {
void Session::notifyKeyCreated(AuthKeyPtr &&key) {
DEBUG_LOG(("AuthKey Info: Session::keyCreated(), setting, dcWithShift %1").arg(dcWithShift));
dc->setKey(key);
dc->setKey(std::move(key));
}
void Session::layerWasInitedForDC(bool wasInited) {
@@ -530,17 +518,17 @@ void Session::tryToReceive() {
}
if (requestId <= 0) {
if (dcWithShift == bareDcId(dcWithShift)) { // call globalCallback only in main session
globalCallback(response.constData(), response.constData() + response.size());
_instance->globalCallback(response.constData(), response.constData() + response.size());
}
} else {
execCallback(requestId, response.constData(), response.constData() + response.size());
_instance->execCallback(requestId, response.constData(), response.constData() + response.size());
}
++cnt;
}
}
Session::~Session() {
t_assert(_connection == 0);
t_assert(_connection == nullptr);
}
MTPrpcError rpcClientError(const QString &type, const QString &description) {