mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-23 03:37:41 +00:00
all deinit moved to Application::aboutToQuit(), mtproto connection thread management refactored, disabled -style=0 fake argument for Application, beta 9028002
This commit is contained in:
parent
08072346fd
commit
99b52d4cc1
@ -1,4 +1,5 @@
|
|||||||
@echo OFF
|
@echo OFF
|
||||||
|
setlocal
|
||||||
|
|
||||||
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ bool update() {
|
|||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (copyTries < 30);
|
} while (copyTries < 100);
|
||||||
if (!copyResult) {
|
if (!copyResult) {
|
||||||
writeLog(L"Error: failed to copy, asking to retry..");
|
writeLog(L"Error: failed to copy, asking to retry..");
|
||||||
WCHAR errMsg[2048];
|
WCHAR errMsg[2048];
|
||||||
|
@ -110,6 +110,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
|
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
|
||||||
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
|
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, SLOT(startApplication()));
|
||||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
@ -127,27 +128,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
|
||||||
App::setQuiting();
|
|
||||||
|
|
||||||
Sandbox::finish();
|
|
||||||
|
|
||||||
delete AppObject;
|
|
||||||
|
|
||||||
_localSocket.close();
|
|
||||||
closeApplication();
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
delete _updateReply;
|
|
||||||
_updateReply = 0;
|
|
||||||
if (_updateChecker) _updateChecker->deleteLater();
|
|
||||||
_updateChecker = 0;
|
|
||||||
if (_updateThread) _updateThread->quit();
|
|
||||||
_updateThread = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Application::socketConnected() {
|
void Application::socketConnected() {
|
||||||
LOG(("Socket connected, this is not the first application instance, sending show command.."));
|
LOG(("Socket connected, this is not the first application instance, sending show command.."));
|
||||||
_secondInstance = true;
|
_secondInstance = true;
|
||||||
@ -333,13 +313,54 @@ void Application::removeClients() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::startApplication() {
|
||||||
|
if (App::quiting()) {
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::closeApplication() {
|
void Application::closeApplication() {
|
||||||
|
App::quit();
|
||||||
|
|
||||||
|
delete AppObject;
|
||||||
|
AppObject = 0;
|
||||||
|
|
||||||
|
Sandbox::finish();
|
||||||
|
|
||||||
_localServer.close();
|
_localServer.close();
|
||||||
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
|
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
|
||||||
disconnect(i->first, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
disconnect(i->first, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
||||||
i->first->close();
|
i->first->close();
|
||||||
}
|
}
|
||||||
_localClients.clear();
|
_localClients.clear();
|
||||||
|
|
||||||
|
_localSocket.close();
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
delete _updateReply;
|
||||||
|
_updateReply = 0;
|
||||||
|
if (_updateChecker) _updateChecker->deleteLater();
|
||||||
|
_updateChecker = 0;
|
||||||
|
if (_updateThread) _updateThread->quit();
|
||||||
|
_updateThread = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUG_LOG(("Telegram finished, result: %1").arg("unknown"));
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
if (cRestartingUpdate()) {
|
||||||
|
DEBUG_LOG(("Application Info: executing updater to install update.."));
|
||||||
|
psExecUpdater();
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (cRestarting()) {
|
||||||
|
DEBUG_LOG(("Application Info: executing Telegram, because of restart.."));
|
||||||
|
psExecTelegram();
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalHandlers::finish();
|
||||||
|
PlatformSpecific::finish();
|
||||||
|
Logs::finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
@ -899,7 +920,7 @@ void AppClass::killDownloadSessions() {
|
|||||||
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {
|
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {
|
||||||
if (i.value() <= ms) {
|
if (i.value() <= ms) {
|
||||||
for (int j = 0; j < MTPDownloadSessionsCount; ++j) {
|
for (int j = 0; j < MTPDownloadSessionsCount; ++j) {
|
||||||
MTP::stopSession(MTP::dld[j] + i.key());
|
MTP::stopSession(MTP::dld(j) + i.key());
|
||||||
}
|
}
|
||||||
i = killDownloadSessionTimes.erase(i);
|
i = killDownloadSessionTimes.erase(i);
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,7 +30,6 @@ class Application : public QApplication {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Application(int &argc, char **argv);
|
Application(int &argc, char **argv);
|
||||||
~Application();
|
|
||||||
|
|
||||||
// Single instance application
|
// Single instance application
|
||||||
public slots:
|
public slots:
|
||||||
@ -41,11 +40,13 @@ public slots:
|
|||||||
void socketWritten(qint64 bytes);
|
void socketWritten(qint64 bytes);
|
||||||
void socketReading();
|
void socketReading();
|
||||||
void newInstanceConnected();
|
void newInstanceConnected();
|
||||||
void closeApplication();
|
|
||||||
|
|
||||||
void readClients();
|
void readClients();
|
||||||
void removeClients();
|
void removeClients();
|
||||||
|
|
||||||
|
void startApplication(); // will be done in exec()
|
||||||
|
void closeApplication(); // will be done in aboutToQuit()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
||||||
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
static const int32 AppVersion = 9028;
|
static const int32 AppVersion = 9028;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.28";
|
static const wchar_t *AppVersionStr = L"0.9.28";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = false;
|
||||||
#define BETA_VERSION (9028001ULL) // just comment this line to build public version
|
#define BETA_VERSION (9028002ULL) // just comment this line to build public version
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
@ -292,7 +292,7 @@ namespace SignalHandlers {
|
|||||||
|
|
||||||
namespace Logs {
|
namespace Logs {
|
||||||
|
|
||||||
Initializer::Initializer() {
|
void start() {
|
||||||
t_assert(LogsData == 0);
|
t_assert(LogsData == 0);
|
||||||
|
|
||||||
if (!Sandbox::CheckBetaVersionDir()) {
|
if (!Sandbox::CheckBetaVersionDir()) {
|
||||||
@ -378,7 +378,7 @@ namespace Logs {
|
|||||||
LOG(("Logs started"));
|
LOG(("Logs started"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer::~Initializer() {
|
void finish() {
|
||||||
delete LogsData;
|
delete LogsData;
|
||||||
LogsData = 0;
|
LogsData = 0;
|
||||||
|
|
||||||
|
@ -23,11 +23,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
class MTPlong;
|
class MTPlong;
|
||||||
namespace Logs {
|
namespace Logs {
|
||||||
|
|
||||||
struct Initializer {
|
void start();
|
||||||
Initializer();
|
|
||||||
~Initializer();
|
|
||||||
};
|
|
||||||
bool started();
|
bool started();
|
||||||
|
void finish();
|
||||||
|
|
||||||
bool instanceChecked();
|
bool instanceChecked();
|
||||||
void multipleInstances();
|
void multipleInstances();
|
||||||
|
@ -25,8 +25,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
settingsParseArgs(argc, argv);
|
settingsParseArgs(argc, argv);
|
||||||
if (cLaunchMode() == LaunchModeFixPrevious) {
|
if (cLaunchMode() == LaunchModeFixPrevious) {
|
||||||
return psFixPrevious();
|
return psFixPrevious();
|
||||||
@ -36,34 +34,15 @@ int main(int argc, char *argv[]) {
|
|||||||
return showCrashReportWindow(QFileInfo(cStartUrl()).absoluteFilePath());
|
return showCrashReportWindow(QFileInfo(cStartUrl()).absoluteFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
Logs::Initializer _logs;
|
// both are finished in Application::closeApplication
|
||||||
{
|
Logs::start(); // must be started before PlatformSpecific is started
|
||||||
PlatformSpecific::Initializer _ps;
|
PlatformSpecific::start(); // must be started before QApplication is created
|
||||||
|
|
||||||
QByteArray args[] = { "-style=0" }; // prepare fake args to disable QT_STYLE_OVERRIDE env variable
|
//QByteArray args[] = { "-style=0" }; // prepare fake args to disable QT_STYLE_OVERRIDE env variable
|
||||||
static const int a_cnt = sizeof(args) / sizeof(args[0]);
|
//static const int a_cnt = sizeof(args) / sizeof(args[0]);
|
||||||
int a_argc = a_cnt + 1;
|
//int a_argc = a_cnt + 1;
|
||||||
char *a_argv[a_cnt + 1] = { argv[0], args[0].data() };
|
//char *a_argv[a_cnt + 1] = { argv[0], args[0].data() };
|
||||||
|
|
||||||
Application app(a_argc, a_argv);
|
Application app(argc, argv);
|
||||||
if (!App::quiting()) {
|
return app.exec();
|
||||||
result = app.exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(("Telegram finished, result: %1").arg(result));
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
if (cRestartingUpdate()) {
|
|
||||||
DEBUG_LOG(("Application Info: executing updater to install update.."));
|
|
||||||
psExecUpdater();
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (cRestarting()) {
|
|
||||||
DEBUG_LOG(("Application Info: executing Telegram, because of restart.."));
|
|
||||||
psExecTelegram();
|
|
||||||
}
|
|
||||||
|
|
||||||
SignalHandlers::finish();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
typedef QMap<int32, MTProtoSessionPtr> Sessions;
|
typedef QMap<int32, MTProtoSession*> Sessions;
|
||||||
Sessions sessions;
|
Sessions sessions;
|
||||||
QVector<MTProtoSessionPtr> sessionsToKill;
|
MTProtoSession *mainSession;
|
||||||
MTProtoSessionPtr mainSession;
|
|
||||||
|
|
||||||
typedef QMap<mtpRequestId, int32> RequestsByDC; // holds dcWithShift for request to this dc or -dc for request to main dc
|
typedef QMap<mtpRequestId, int32> RequestsByDC; // holds dcWithShift for request to this dc or -dc for request to main dc
|
||||||
RequestsByDC requestsByDC;
|
RequestsByDC requestsByDC;
|
||||||
@ -62,13 +61,16 @@ namespace {
|
|||||||
typedef QMap<int32, DCAuthWaiters> AuthWaiters; // holds request ids waiting for auth import to specific dc
|
typedef QMap<int32, DCAuthWaiters> AuthWaiters; // holds request ids waiting for auth import to specific dc
|
||||||
AuthWaiters authWaiters;
|
AuthWaiters authWaiters;
|
||||||
|
|
||||||
|
typedef OrderedSet<MTProtoConnection*> MTPQuittingConnections;
|
||||||
|
MTPQuittingConnections quittingConnections;
|
||||||
|
|
||||||
QMutex toClearLock;
|
QMutex toClearLock;
|
||||||
RPCCallbackClears toClear;
|
RPCCallbackClears toClear;
|
||||||
|
|
||||||
RPCResponseHandler globalHandler;
|
RPCResponseHandler globalHandler;
|
||||||
MTPStateChangedHandler stateChangedHandler = 0;
|
MTPStateChangedHandler stateChangedHandler = 0;
|
||||||
MTPSessionResetHandler sessionResetHandler = 0;
|
MTPSessionResetHandler sessionResetHandler = 0;
|
||||||
_mtp_internal::RequestResender *resender = 0;
|
_mtp_internal::GlobalSlotCarrier *_globalSlotCarrier = 0;
|
||||||
|
|
||||||
void importDone(const MTPauth_Authorization &result, mtpRequestId req) {
|
void importDone(const MTPauth_Authorization &result, mtpRequestId req) {
|
||||||
QMutexLocker locker1(&requestByDCLock);
|
QMutexLocker locker1(&requestByDCLock);
|
||||||
@ -111,7 +113,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
DEBUG_LOG(("MTP Info: resending request %1 to dc %2 after import auth").arg(requestId).arg(k.value()));
|
DEBUG_LOG(("MTP Info: resending request %1 to dc %2 after import auth").arg(requestId).arg(k.value()));
|
||||||
}
|
}
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dcWithShift)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift)) {
|
||||||
session->sendPrepared(j.value());
|
session->sendPrepared(j.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,7 +204,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
req = i.value();
|
req = i.value();
|
||||||
}
|
}
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(newdcWithShift)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(newdcWithShift)) {
|
||||||
_mtp_internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
|
_mtp_internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
|
||||||
session->sendPrepared(req);
|
session->sendPrepared(req);
|
||||||
}
|
}
|
||||||
@ -230,7 +232,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
delayedRequests.insert(i, DelayedRequest(requestId, sendAt));
|
delayedRequests.insert(i, DelayedRequest(requestId, sendAt));
|
||||||
|
|
||||||
if (resender) resender->checkDelayed();
|
if (_globalSlotCarrier) _globalSlotCarrier->checkDelayed();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (code == 401 || (badGuestDC && badGuestDCRequests.constFind(requestId) == badGuestDCRequests.cend())) {
|
} else if (code == 401 || (badGuestDC && badGuestDCRequests.constFind(requestId) == badGuestDCRequests.cend())) {
|
||||||
@ -281,7 +283,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
if (!dcWithShift) return false;
|
if (!dcWithShift) return false;
|
||||||
|
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
||||||
req->needsLayer = true;
|
req->needsLayer = true;
|
||||||
session->sendPrepared(req);
|
session->sendPrepared(req);
|
||||||
}
|
}
|
||||||
@ -319,7 +321,7 @@ namespace {
|
|||||||
if (!dcWithShift) return false;
|
if (!dcWithShift) return false;
|
||||||
|
|
||||||
if (!req->after) {
|
if (!req->after) {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
||||||
req->needsLayer = true;
|
req->needsLayer = true;
|
||||||
session->sendPrepared(req);
|
session->sendPrepared(req);
|
||||||
}
|
}
|
||||||
@ -346,7 +348,7 @@ namespace {
|
|||||||
delayedRequests.insert(i, DelayedRequest(requestId, i->second));
|
delayedRequests.insert(i, DelayedRequest(requestId, i->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resender) resender->checkDelayed();
|
if (_globalSlotCarrier) _globalSlotCarrier->checkDelayed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -360,21 +362,18 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace _mtp_internal {
|
namespace _mtp_internal {
|
||||||
MTProtoSessionPtr getSession(int32 dcWithShift) {
|
MTProtoSession *getSession(int32 dcWithShift) {
|
||||||
if (!_started) return MTProtoSessionPtr();
|
if (!_started) return 0;
|
||||||
if (!dcWithShift) return mainSession;
|
if (!dcWithShift) return mainSession;
|
||||||
if (!(dcWithShift % _mtp_internal::dcShift)) {
|
if (!(dcWithShift % _mtp_internal::dcShift)) {
|
||||||
dcWithShift += (mainSession->getDcWithShift() % _mtp_internal::dcShift);
|
dcWithShift += (mainSession->getDcWithShift() % _mtp_internal::dcShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sessions::const_iterator i = sessions.constFind(dcWithShift);
|
Sessions::const_iterator i = sessions.constFind(dcWithShift);
|
||||||
if (i != sessions.cend()) return *i;
|
if (i == sessions.cend()) {
|
||||||
|
i = sessions.insert(dcWithShift, new MTProtoSession(dcWithShift));
|
||||||
MTProtoSessionPtr result(new MTProtoSession());
|
}
|
||||||
result->start(dcWithShift);
|
return i.value();
|
||||||
|
|
||||||
sessions.insert(dcWithShift, result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool paused() {
|
bool paused() {
|
||||||
@ -580,11 +579,11 @@ namespace _mtp_internal {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestResender::RequestResender() {
|
GlobalSlotCarrier::GlobalSlotCarrier() {
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(checkDelayed()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(checkDelayed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestResender::checkDelayed() {
|
void GlobalSlotCarrier::checkDelayed() {
|
||||||
uint64 now = getms(true);
|
uint64 now = getms(true);
|
||||||
while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) {
|
while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) {
|
||||||
mtpRequestId requestId = delayedRequests.front().first;
|
mtpRequestId requestId = delayedRequests.front().first;
|
||||||
@ -612,7 +611,7 @@ namespace _mtp_internal {
|
|||||||
}
|
}
|
||||||
req = j.value();
|
req = j.value();
|
||||||
}
|
}
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) {
|
||||||
session->sendPrepared(req);
|
session->sendPrepared(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,6 +620,25 @@ namespace _mtp_internal {
|
|||||||
_timer.start(delayedRequests.front().second - now);
|
_timer.start(delayedRequests.front().second - now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlobalSlotCarrier::connectionFinished(MTProtoConnection *connection) {
|
||||||
|
MTPQuittingConnections::iterator i = quittingConnections.find(connection);
|
||||||
|
if (i != quittingConnections.cend()) {
|
||||||
|
quittingConnections.erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->waitTillFinish();
|
||||||
|
delete connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalSlotCarrier *globalSlotCarrier() {
|
||||||
|
return _globalSlotCarrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void queueQuittingConnection(MTProtoConnection *connection) {
|
||||||
|
quittingConnections.insert(connection);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
@ -637,12 +655,12 @@ namespace MTP {
|
|||||||
|
|
||||||
MTProtoDCMap &dcs(mtpDCMap());
|
MTProtoDCMap &dcs(mtpDCMap());
|
||||||
|
|
||||||
mainSession = MTProtoSessionPtr(new MTProtoSession());
|
_globalSlotCarrier = new _mtp_internal::GlobalSlotCarrier();
|
||||||
mainSession->start(mtpMainDC());
|
|
||||||
sessions[mainSession->getDcWithShift()] = mainSession;
|
mainSession = new MTProtoSession(mtpMainDC());
|
||||||
|
sessions.insert(mainSession->getDcWithShift(), mainSession);
|
||||||
|
|
||||||
_started = true;
|
_started = true;
|
||||||
resender = new _mtp_internal::RequestResender();
|
|
||||||
|
|
||||||
if (mtpNeedConfig()) {
|
if (mtpNeedConfig()) {
|
||||||
mtpConfigLoader()->load();
|
mtpConfigLoader()->load();
|
||||||
@ -657,7 +675,7 @@ namespace MTP {
|
|||||||
if (!_started) return;
|
if (!_started) return;
|
||||||
|
|
||||||
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
||||||
(*i)->restart();
|
i.value()->restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,8 +684,8 @@ namespace MTP {
|
|||||||
|
|
||||||
dcMask %= _mtp_internal::dcShift;
|
dcMask %= _mtp_internal::dcShift;
|
||||||
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
||||||
if (((*i)->getDcWithShift() % int(_mtp_internal::dcShift)) == dcMask) {
|
if ((i.value()->getDcWithShift() % int(_mtp_internal::dcShift)) == dcMask) {
|
||||||
(*i)->restart();
|
i.value()->restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,7 +699,7 @@ namespace MTP {
|
|||||||
if (!_started) return;
|
if (!_started) return;
|
||||||
_paused = false;
|
_paused = false;
|
||||||
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
||||||
(*i)->unpaused();
|
i.value()->unpaused();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,7 +732,7 @@ namespace MTP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sessions::const_iterator i = sessions.constFind(dc);
|
Sessions::const_iterator i = sessions.constFind(dc);
|
||||||
if (i != sessions.cend()) return (*i)->getState();
|
if (i != sessions.cend()) return i.value()->getState();
|
||||||
|
|
||||||
return MTProtoConnection::Disconnected;
|
return MTProtoConnection::Disconnected;
|
||||||
}
|
}
|
||||||
@ -728,13 +746,13 @@ namespace MTP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sessions::const_iterator i = sessions.constFind(dc);
|
Sessions::const_iterator i = sessions.constFind(dc);
|
||||||
if (i != sessions.cend()) return (*i)->transport();
|
if (i != sessions.cend()) return i.value()->transport();
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ping() {
|
void ping() {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(0)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(0)) {
|
||||||
session->ping();
|
session->ping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -754,7 +772,7 @@ namespace MTP {
|
|||||||
QMutexLocker locker(&requestByDCLock);
|
QMutexLocker locker(&requestByDCLock);
|
||||||
RequestsByDC::iterator i = requestsByDC.find(requestId);
|
RequestsByDC::iterator i = requestsByDC.find(requestId);
|
||||||
if (i != requestsByDC.end()) {
|
if (i != requestsByDC.end()) {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(abs(i.value()))) {
|
if (MTProtoSession *session = _mtp_internal::getSession(abs(i.value()))) {
|
||||||
session->cancel(requestId, msgId);
|
session->cancel(requestId, msgId);
|
||||||
}
|
}
|
||||||
requestsByDC.erase(i);
|
requestsByDC.erase(i);
|
||||||
@ -763,26 +781,25 @@ namespace MTP {
|
|||||||
_mtp_internal::clearCallbacks(requestId);
|
_mtp_internal::clearCallbacks(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void killSessionsDelayed() {
|
|
||||||
if (!sessionsToKill.isEmpty()) {
|
|
||||||
sessionsToKill.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void killSession(int32 dc) {
|
void killSession(int32 dc) {
|
||||||
Sessions::iterator i = sessions.find(dc);
|
Sessions::iterator i = sessions.find(dc);
|
||||||
if (i != sessions.end()) {
|
if (i != sessions.cend()) {
|
||||||
bool wasMain = (i.value() == mainSession);
|
bool wasMain = (i.value() == mainSession);
|
||||||
|
|
||||||
i.value()->kill();
|
i.value()->kill();
|
||||||
if (sessionsToKill.isEmpty()) QTimer::singleShot(0, killSessionsDelayed);
|
i.value()->deleteLater();
|
||||||
sessionsToKill.push_back(i.value());
|
|
||||||
sessions.erase(i);
|
sessions.erase(i);
|
||||||
|
|
||||||
if (wasMain) {
|
if (wasMain) {
|
||||||
mainSession = MTProtoSessionPtr(new MTProtoSession());
|
mainSession = new MTProtoSession(mtpMainDC());
|
||||||
mainSession->start(mtpMainDC());
|
int32 newdc = mainSession->getDcWithShift();
|
||||||
sessions[mainSession->getDcWithShift()] = mainSession;
|
i = sessions.find(newdc);
|
||||||
|
if (i != sessions.cend()) {
|
||||||
|
i.value()->kill();
|
||||||
|
i.value()->deleteLater();
|
||||||
|
sessions.erase(i);
|
||||||
|
}
|
||||||
|
sessions.insert(newdc, mainSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,14 +818,14 @@ namespace MTP {
|
|||||||
QMutexLocker locker(&requestByDCLock);
|
QMutexLocker locker(&requestByDCLock);
|
||||||
RequestsByDC::iterator i = requestsByDC.find(requestId);
|
RequestsByDC::iterator i = requestsByDC.find(requestId);
|
||||||
if (i != requestsByDC.end()) {
|
if (i != requestsByDC.end()) {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(abs(i.value()))) {
|
if (MTProtoSession *session = _mtp_internal::getSession(abs(i.value()))) {
|
||||||
return session->requestState(requestId);
|
return session->requestState(requestId);
|
||||||
}
|
}
|
||||||
return MTP::RequestConnecting;
|
return MTP::RequestConnecting;
|
||||||
}
|
}
|
||||||
return MTP::RequestSent;
|
return MTP::RequestSent;
|
||||||
}
|
}
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(-requestId)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(-requestId)) {
|
||||||
return session->requestState(0);
|
return session->requestState(0);
|
||||||
}
|
}
|
||||||
return MTP::RequestConnecting;
|
return MTP::RequestConnecting;
|
||||||
@ -817,11 +834,20 @@ namespace MTP {
|
|||||||
void stop() {
|
void stop() {
|
||||||
for (Sessions::iterator i = sessions.begin(), e = sessions.end(); i != e; ++i) {
|
for (Sessions::iterator i = sessions.begin(), e = sessions.end(); i != e; ++i) {
|
||||||
i.value()->kill();
|
i.value()->kill();
|
||||||
|
delete i.value();
|
||||||
}
|
}
|
||||||
sessions.clear();
|
sessions.clear();
|
||||||
mainSession = MTProtoSessionPtr();
|
mainSession = nullptr;
|
||||||
delete resender;
|
|
||||||
resender = 0;
|
for (MTPQuittingConnections::const_iterator i = quittingConnections.cbegin(), e = quittingConnections.cend(); i != e; ++i) {
|
||||||
|
i.key()->waitTillFinish();
|
||||||
|
delete i.key();
|
||||||
|
}
|
||||||
|
quittingConnections.clear();
|
||||||
|
|
||||||
|
delete _globalSlotCarrier;
|
||||||
|
_globalSlotCarrier = nullptr;
|
||||||
|
|
||||||
mtpDestroyConfigLoader();
|
mtpDestroyConfigLoader();
|
||||||
|
|
||||||
_started = false;
|
_started = false;
|
||||||
|
@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
#include "mtproto/mtpFileLoader.h"
|
#include "mtproto/mtpFileLoader.h"
|
||||||
|
|
||||||
namespace _mtp_internal {
|
namespace _mtp_internal {
|
||||||
MTProtoSessionPtr getSession(int32 dc = 0); // 0 - current set dc
|
MTProtoSession *getSession(int32 dc); // 0 - current set dc
|
||||||
|
|
||||||
bool paused();
|
bool paused();
|
||||||
|
|
||||||
@ -49,21 +49,28 @@ namespace _mtp_internal {
|
|||||||
return rpcErrorOccured(requestId, handler.onFail, err);
|
return rpcErrorOccured(requestId, handler.onFail, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestResender : public QObject {
|
// used for:
|
||||||
|
// - resending requests by timer which were postponed by flood delay
|
||||||
|
// - destroying MTProtoConnections whose thread has finished
|
||||||
|
class GlobalSlotCarrier : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RequestResender();
|
GlobalSlotCarrier();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void checkDelayed();
|
void checkDelayed();
|
||||||
|
void connectionFinished(MTProtoConnection *connection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SingleTimer _timer;
|
SingleTimer _timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GlobalSlotCarrier *globalSlotCarrier();
|
||||||
|
void queueQuittingConnection(MTProtoConnection *connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
@ -99,7 +106,7 @@ namespace MTP {
|
|||||||
|
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
|
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dc)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dc)) {
|
||||||
return session->send(request, callbacks, msCanWait, true, !dc, after);
|
return session->send(request, callbacks, msCanWait, true, !dc, after);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -109,7 +116,7 @@ namespace MTP {
|
|||||||
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after);
|
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after);
|
||||||
}
|
}
|
||||||
inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) {
|
inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) {
|
||||||
if (MTProtoSessionPtr session = _mtp_internal::getSession(dc)) {
|
if (MTProtoSession *session = _mtp_internal::getSession(dc)) {
|
||||||
return session->sendAnything(msCanWait);
|
return session->sendAnything(msCanWait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,8 +252,6 @@ namespace {
|
|||||||
typedef QMap<uint64, mtpPublicRSA> PublicRSAKeys;
|
typedef QMap<uint64, mtpPublicRSA> PublicRSAKeys;
|
||||||
PublicRSAKeys gPublicRSA;
|
PublicRSAKeys gPublicRSA;
|
||||||
|
|
||||||
MTProtoConnection gMainConnection;
|
|
||||||
|
|
||||||
bool gConfigInited = false;
|
bool gConfigInited = false;
|
||||||
void initRSAConfig() {
|
void initRSAConfig() {
|
||||||
if (gConfigInited) return;
|
if (gConfigInited) return;
|
||||||
@ -277,66 +275,75 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTPThread::MTPThread(QObject *parent) : QThread(parent) {
|
uint32 MTPThreadIdIncrement = 0;
|
||||||
static uint32 gThreadId = 0;
|
|
||||||
threadId = ++gThreadId;
|
MTPThread::MTPThread() : QThread(0)
|
||||||
|
, _threadId(++MTPThreadIdIncrement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MTPThread::getThreadId() const {
|
uint32 MTPThread::getThreadId() const {
|
||||||
return threadId;
|
return _threadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTProtoConnection::MTProtoConnection() : thread(0), data(0) {
|
MTPThread::~MTPThread() {
|
||||||
|
}
|
||||||
|
|
||||||
|
MTProtoConnection::MTProtoConnection() : thread(nullptr), data(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MTProtoConnection::start(MTPSessionData *sessionData, int32 dc) {
|
int32 MTProtoConnection::start(MTPSessionData *sessionData, int32 dc) {
|
||||||
|
t_assert(thread == nullptr && data == nullptr);
|
||||||
|
|
||||||
initRSAConfig();
|
initRSAConfig();
|
||||||
|
|
||||||
if (thread) {
|
thread = new MTPThread();
|
||||||
DEBUG_LOG(("MTP Info: MTP start called for already working connection"));
|
|
||||||
return dc;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread = new MTPThread(QApplication::instance());
|
|
||||||
data = new MTProtoConnectionPrivate(thread, this, sessionData, dc);
|
data = new MTProtoConnectionPrivate(thread, this, sessionData, dc);
|
||||||
|
|
||||||
dc = data->getDC();
|
dc = data->getDC();
|
||||||
if (!dc) {
|
if (!dc) {
|
||||||
delete data;
|
delete data;
|
||||||
|
data = nullptr;
|
||||||
delete thread;
|
delete thread;
|
||||||
data = 0;
|
thread = nullptr;
|
||||||
thread = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->start();
|
thread->start();
|
||||||
return dc;
|
return dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnection::stop() {
|
void MTProtoConnection::kill() {
|
||||||
if (data) data->stop();
|
t_assert(data != nullptr && thread != nullptr);
|
||||||
if (thread) thread->quit();
|
data->stop();
|
||||||
|
data = nullptr; // will be deleted in thread::finished signal
|
||||||
|
thread->quit();
|
||||||
|
_mtp_internal::queueQuittingConnection(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnection::stopped() {
|
void MTProtoConnection::waitTillFinish() {
|
||||||
if (thread) thread->deleteLater();
|
t_assert(data == nullptr && thread != nullptr);
|
||||||
if (data) data->deleteLater();
|
|
||||||
thread = 0;
|
thread->wait();
|
||||||
data = 0;
|
delete thread;
|
||||||
delete this;
|
thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MTProtoConnection::state() const {
|
int32 MTProtoConnection::state() const {
|
||||||
if (!data) return Disconnected;
|
t_assert(data != nullptr && thread != nullptr);
|
||||||
|
|
||||||
return data->getState();
|
return data->getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MTProtoConnection::transport() const {
|
QString MTProtoConnection::transport() const {
|
||||||
if (!data) return QString();
|
t_assert(data != nullptr && thread != nullptr);
|
||||||
|
|
||||||
return data->transport();
|
return data->transport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTProtoConnection::~MTProtoConnection() {
|
||||||
|
t_assert(data == nullptr && thread == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
mtpBuffer _handleHttpResponse(QNetworkReply *reply) {
|
mtpBuffer _handleHttpResponse(QNetworkReply *reply) {
|
||||||
QByteArray response = reply->readAll();
|
QByteArray response = reply->readAll();
|
||||||
@ -1311,30 +1318,31 @@ void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 _dc)
|
MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 _dc) : QObject(0)
|
||||||
: QObject(0)
|
, _state(MTProtoConnection::Disconnected)
|
||||||
, _state(MTProtoConnection::Disconnected)
|
, _needSessionReset(false)
|
||||||
, _needSessionReset(false)
|
, dc(_dc)
|
||||||
, dc(_dc)
|
, _owner(owner)
|
||||||
, _owner(owner)
|
, _conn(0)
|
||||||
, _conn(0), _conn4(0), _conn6(0)
|
, _conn4(0)
|
||||||
, retryTimeout(1)
|
, _conn6(0)
|
||||||
, oldConnection(true)
|
, retryTimeout(1)
|
||||||
, _waitForReceived(MTPMinReceiveDelay)
|
, oldConnection(true)
|
||||||
, _waitForConnected(MTPMinConnectDelay)
|
, _waitForReceived(MTPMinReceiveDelay)
|
||||||
, firstSentAt(-1)
|
, _waitForConnected(MTPMinConnectDelay)
|
||||||
, _pingId(0)
|
, firstSentAt(-1)
|
||||||
, _pingIdToSend(0)
|
, _pingId(0)
|
||||||
, _pingSendAt(0)
|
, _pingIdToSend(0)
|
||||||
, _pingMsgId(0)
|
, _pingSendAt(0)
|
||||||
, restarted(false)
|
, _pingMsgId(0)
|
||||||
, keyId(0)
|
, restarted(false)
|
||||||
|
, _finished(false)
|
||||||
|
, keyId(0)
|
||||||
// , sessionDataMutex(QReadWriteLock::Recursive)
|
// , sessionDataMutex(QReadWriteLock::Recursive)
|
||||||
, sessionData(data)
|
, sessionData(data)
|
||||||
, myKeyLock(false)
|
, myKeyLock(false)
|
||||||
, authKeyData(0)
|
, authKeyData(0)
|
||||||
, authKeyStrings(0) {
|
, authKeyStrings(0) {
|
||||||
|
|
||||||
oldConnectionTimer.moveToThread(thread);
|
oldConnectionTimer.moveToThread(thread);
|
||||||
_waitForConnectedTimer.moveToThread(thread);
|
_waitForConnectedTimer.moveToThread(thread);
|
||||||
_waitForReceivedTimer.moveToThread(thread);
|
_waitForReceivedTimer.moveToThread(thread);
|
||||||
@ -1357,6 +1365,7 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
|
|||||||
|
|
||||||
connect(thread, SIGNAL(started()), this, SLOT(socketStart()));
|
connect(thread, SIGNAL(started()), this, SLOT(socketStart()));
|
||||||
connect(thread, SIGNAL(finished()), this, SLOT(doFinish()));
|
connect(thread, SIGNAL(finished()), this, SLOT(doFinish()));
|
||||||
|
connect(this, SIGNAL(finished(MTProtoConnection*)), _mtp_internal::globalSlotCarrier(), SLOT(connectionFinished(MTProtoConnection*)), Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(&retryTimer, SIGNAL(timeout()), this, SLOT(retryByTimer()));
|
connect(&retryTimer, SIGNAL(timeout()), this, SLOT(retryByTimer()));
|
||||||
connect(&_waitForConnectedTimer, SIGNAL(timeout()), this, SLOT(onWaitConnectedFailed()));
|
connect(&_waitForConnectedTimer, SIGNAL(timeout()), this, SLOT(onWaitConnectedFailed()));
|
||||||
@ -1966,6 +1975,10 @@ void MTProtoConnectionPrivate::restartNow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
||||||
|
if (_finished) {
|
||||||
|
DEBUG_LOG(("MTP Error: socketStart() called for finished connection!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool isDldDc = (dc >= MTP::dldStart) && (dc < MTP::dldEnd);
|
bool isDldDc = (dc >= MTP::dldStart) && (dc < MTP::dldEnd);
|
||||||
if (isDldDc) { // using media_only addresses only if key for this dc is already created
|
if (isDldDc) { // using media_only addresses only if key for this dc is already created
|
||||||
QReadLocker lockFinished(&sessionDataMutex);
|
QReadLocker lockFinished(&sessionDataMutex);
|
||||||
@ -2231,7 +2244,9 @@ void MTProtoConnectionPrivate::doDisconnect() {
|
|||||||
|
|
||||||
void MTProtoConnectionPrivate::doFinish() {
|
void MTProtoConnectionPrivate::doFinish() {
|
||||||
doDisconnect();
|
doDisconnect();
|
||||||
_owner->stopped();
|
_finished = true;
|
||||||
|
emit finished(_owner);
|
||||||
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::handleReceived() {
|
void MTProtoConnectionPrivate::handleReceived() {
|
||||||
@ -3928,7 +3943,7 @@ void MTProtoConnectionPrivate::unlockKey() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTProtoConnectionPrivate::~MTProtoConnectionPrivate() {
|
MTProtoConnectionPrivate::~MTProtoConnectionPrivate() {
|
||||||
doDisconnect();
|
t_assert(_finished && _conn == nullptr && _conn4 == nullptr && _conn6 == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::stop() {
|
void MTProtoConnectionPrivate::stop() {
|
||||||
@ -3939,9 +3954,6 @@ void MTProtoConnectionPrivate::stop() {
|
|||||||
sessionData->keyMutex()->unlock();
|
sessionData->keyMutex()->unlock();
|
||||||
myKeyLock = false;
|
myKeyLock = false;
|
||||||
}
|
}
|
||||||
sessionData = 0;
|
sessionData = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTProtoConnection::~MTProtoConnection() {
|
|
||||||
}
|
|
||||||
|
@ -58,11 +58,13 @@ class MTPThread : public QThread {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MTPThread(QObject *parent = 0);
|
MTPThread();
|
||||||
uint32 getThreadId() const;
|
uint32 getThreadId() const;
|
||||||
|
~MTPThread();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 threadId;
|
uint32 _threadId;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTProtoConnection {
|
class MTProtoConnection {
|
||||||
@ -75,8 +77,8 @@ public:
|
|||||||
|
|
||||||
MTProtoConnection();
|
MTProtoConnection();
|
||||||
int32 start(MTPSessionData *data, int32 dc = 0); // return dc
|
int32 start(MTPSessionData *data, int32 dc = 0); // return dc
|
||||||
void stop();
|
void kill();
|
||||||
void stopped();
|
void waitTillFinish();
|
||||||
~MTProtoConnection();
|
~MTProtoConnection();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -358,6 +360,8 @@ signals:
|
|||||||
void resendManyAsync(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
void resendManyAsync(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
||||||
void resendAllAsync();
|
void resendAllAsync();
|
||||||
|
|
||||||
|
void finished(MTProtoConnection *connection);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void retryByTimer();
|
void retryByTimer();
|
||||||
@ -466,7 +470,7 @@ private:
|
|||||||
template <typename TResponse>
|
template <typename TResponse>
|
||||||
bool readResponseNotSecure(TResponse &response);
|
bool readResponseNotSecure(TResponse &response);
|
||||||
|
|
||||||
bool restarted;
|
bool restarted, _finished;
|
||||||
|
|
||||||
uint64 keyId;
|
uint64 keyId;
|
||||||
QReadWriteLock sessionDataMutex;
|
QReadWriteLock sessionDataMutex;
|
||||||
|
@ -66,7 +66,8 @@ void MTPSessionData::clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MTProtoSession::MTProtoSession() : QObject()
|
MTProtoSession::MTProtoSession(int32 dcenter) : QObject()
|
||||||
|
, _connection(0)
|
||||||
, _killed(false)
|
, _killed(false)
|
||||||
, _needToReceive(false)
|
, _needToReceive(false)
|
||||||
, data(this)
|
, data(this)
|
||||||
@ -75,9 +76,6 @@ MTProtoSession::MTProtoSession() : QObject()
|
|||||||
, msSendCall(0)
|
, msSendCall(0)
|
||||||
, msWait(0)
|
, msWait(0)
|
||||||
, _ping(false) {
|
, _ping(false) {
|
||||||
}
|
|
||||||
|
|
||||||
void MTProtoSession::start(int32 dcenter) {
|
|
||||||
if (_killed) {
|
if (_killed) {
|
||||||
DEBUG_LOG(("Session Error: can't start a killed session"));
|
DEBUG_LOG(("Session Error: can't start a killed session"));
|
||||||
return;
|
return;
|
||||||
@ -96,37 +94,32 @@ void MTProtoSession::start(int32 dcenter) {
|
|||||||
|
|
||||||
MTProtoDCMap &dcs(mtpDCMap());
|
MTProtoDCMap &dcs(mtpDCMap());
|
||||||
|
|
||||||
connections.reserve(cConnectionsInSession());
|
_connection = new MTProtoConnection();
|
||||||
for (uint32 i = 0; i < cConnectionsInSession(); ++i) {
|
dcWithShift = _connection->start(&data, dcenter);
|
||||||
connections.push_back(new MTProtoConnection());
|
if (!dcWithShift) {
|
||||||
dcWithShift = connections.back()->start(&data, dcenter);
|
delete _connection;
|
||||||
if (!dcWithShift) {
|
_connection = 0;
|
||||||
for (MTProtoConnections::const_iterator j = connections.cbegin(), e = connections.cend(); j != e; ++j) {
|
DEBUG_LOG(("Session Info: could not start connection to dc %1").arg(dcenter));
|
||||||
delete *j;
|
return;
|
||||||
}
|
}
|
||||||
connections.clear();
|
if (!dc) {
|
||||||
DEBUG_LOG(("Session Info: could not start connection %1 to dc %2").arg(i).arg(dcenter));
|
dcenter = dcWithShift;
|
||||||
return;
|
int32 dcId = dcWithShift % _mtp_internal::dcShift;
|
||||||
|
MTProtoDCMap::const_iterator dcIndex = dcs.constFind(dcId);
|
||||||
|
if (dcIndex == dcs.cend()) {
|
||||||
|
dc = MTProtoDCPtr(new MTProtoDC(dcId, mtpAuthKeyPtr()));
|
||||||
|
dcs.insert(dcWithShift % _mtp_internal::dcShift, dc);
|
||||||
|
} else {
|
||||||
|
dc = dcIndex.value();
|
||||||
}
|
}
|
||||||
if (!dc) {
|
|
||||||
dcenter = dcWithShift;
|
|
||||||
int32 dcId = dcWithShift % _mtp_internal::dcShift;
|
|
||||||
MTProtoDCMap::const_iterator dcIndex = dcs.constFind(dcId);
|
|
||||||
if (dcIndex == dcs.cend()) {
|
|
||||||
dc = MTProtoDCPtr(new MTProtoDC(dcId, mtpAuthKeyPtr()));
|
|
||||||
dcs.insert(dcWithShift % _mtp_internal::dcShift, dc);
|
|
||||||
} else {
|
|
||||||
dc = dcIndex.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadLockerAttempt lock(keyMutex());
|
ReadLockerAttempt lock(keyMutex());
|
||||||
data.setKey(lock ? dc->getKey() : mtpAuthKeyPtr(0));
|
data.setKey(lock ? dc->getKey() : mtpAuthKeyPtr(0));
|
||||||
if (lock && dc->connectionInited()) {
|
if (lock && dc->connectionInited()) {
|
||||||
data.setLayerWasInited(true);
|
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.data(), SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC()), Qt::QueuedConnection);
|
||||||
|
connect(dc.data(), SIGNAL(layerWasInited(bool)), this, SLOT(layerWasInitedForDC(bool)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +132,14 @@ void MTProtoSession::restart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoSession::stop() {
|
void MTProtoSession::stop() {
|
||||||
|
if (_killed) {
|
||||||
|
DEBUG_LOG(("Session Error: can't kill a killed session"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
DEBUG_LOG(("Session Info: stopping session dcWithShift %1").arg(dcWithShift));
|
DEBUG_LOG(("Session Info: stopping session dcWithShift %1").arg(dcWithShift));
|
||||||
while (!connections.isEmpty()) {
|
if (_connection) {
|
||||||
connections.back()->stop();
|
_connection->kill();
|
||||||
connections.pop_back();
|
_connection = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,22 +191,17 @@ void MTProtoSession::needToResumeAndSend() {
|
|||||||
DEBUG_LOG(("Session Info: can't resume a killed session"));
|
DEBUG_LOG(("Session Info: can't resume a killed session"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (connections.isEmpty()) {
|
if (!_connection) {
|
||||||
DEBUG_LOG(("Session Info: resuming session dcWithShift %1").arg(dcWithShift));
|
DEBUG_LOG(("Session Info: resuming session dcWithShift %1").arg(dcWithShift));
|
||||||
MTProtoDCMap &dcs(mtpDCMap());
|
MTProtoDCMap &dcs(mtpDCMap());
|
||||||
|
|
||||||
connections.reserve(cConnectionsInSession());
|
_connection = new MTProtoConnection();
|
||||||
for (uint32 i = 0; i < cConnectionsInSession(); ++i) {
|
if (!_connection->start(&data, dcWithShift)) {
|
||||||
connections.push_back(new MTProtoConnection());
|
delete _connection;
|
||||||
if (!connections.back()->start(&data, dcWithShift)) {
|
_connection = 0;
|
||||||
for (MTProtoConnections::const_iterator j = connections.cbegin(), e = connections.cend(); j != e; ++j) {
|
DEBUG_LOG(("Session Info: could not start connection to dcWithShift %1").arg(dcWithShift));
|
||||||
delete *j;
|
dcWithShift = 0;
|
||||||
}
|
return;
|
||||||
connections.clear();
|
|
||||||
DEBUG_LOG(("Session Info: could not start connection %1 to dcWithShift %2").arg(i).arg(dcWithShift));
|
|
||||||
dcWithShift = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_ping) {
|
if (_ping) {
|
||||||
@ -324,12 +316,13 @@ void MTProtoSession::ping() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 MTProtoSession::requestState(mtpRequestId requestId) const {
|
int32 MTProtoSession::requestState(mtpRequestId requestId) const {
|
||||||
MTProtoConnections::const_iterator j = connections.cbegin(), e = connections.cend();
|
|
||||||
int32 result = MTP::RequestSent;
|
int32 result = MTP::RequestSent;
|
||||||
for (; j != e; ++j) {
|
|
||||||
int32 s = (*j)->state();
|
bool connected = false;
|
||||||
|
if (_connection) {
|
||||||
|
int32 s = _connection->state();
|
||||||
if (s == MTProtoConnection::Connected) {
|
if (s == MTProtoConnection::Connected) {
|
||||||
break;
|
connected = true;
|
||||||
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) {
|
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) {
|
||||||
if (result < 0 || result == MTP::RequestSent) {
|
if (result < 0 || result == MTP::RequestSent) {
|
||||||
result = MTP::RequestConnecting;
|
result = MTP::RequestConnecting;
|
||||||
@ -340,7 +333,7 @@ int32 MTProtoSession::requestState(mtpRequestId requestId) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == e) { // no one is connected
|
if (!connected) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (!requestId) return MTP::RequestSent;
|
if (!requestId) return MTP::RequestSent;
|
||||||
@ -356,10 +349,10 @@ int32 MTProtoSession::requestState(mtpRequestId requestId) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 MTProtoSession::getState() const {
|
int32 MTProtoSession::getState() const {
|
||||||
MTProtoConnections::const_iterator j = connections.cbegin(), e = connections.cend();
|
|
||||||
int32 result = -86400000;
|
int32 result = -86400000;
|
||||||
for (; j != e; ++j) {
|
|
||||||
int32 s = (*j)->state();
|
if (_connection) {
|
||||||
|
int32 s = _connection->state();
|
||||||
if (s == MTProtoConnection::Connected) {
|
if (s == MTProtoConnection::Connected) {
|
||||||
return s;
|
return s;
|
||||||
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) {
|
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) {
|
||||||
@ -379,12 +372,7 @@ int32 MTProtoSession::getState() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString MTProtoSession::transport() const {
|
QString MTProtoSession::transport() const {
|
||||||
MTProtoConnections::const_iterator j = connections.cbegin(), e = connections.cend();
|
return _connection ? _connection->transport() : QString();
|
||||||
for (; j != e; ++j) {
|
|
||||||
QString s = (*j)->transport();
|
|
||||||
if (!s.isEmpty()) return s;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpRequestId MTProtoSession::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
mtpRequestId MTProtoSession::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
||||||
@ -507,6 +495,10 @@ int32 MTProtoSession::getDcWithShift() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoSession::tryToReceive() {
|
void MTProtoSession::tryToReceive() {
|
||||||
|
if (_killed) {
|
||||||
|
DEBUG_LOG(("Session Error: can't receive in a killed session"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_mtp_internal::paused()) {
|
if (_mtp_internal::paused()) {
|
||||||
_needToReceive = true;
|
_needToReceive = true;
|
||||||
return;
|
return;
|
||||||
@ -537,9 +529,7 @@ void MTProtoSession::tryToReceive() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTProtoSession::~MTProtoSession() {
|
MTProtoSession::~MTProtoSession() {
|
||||||
for (MTProtoConnections::const_iterator i = connections.cbegin(), e = connections.cend(); i != e; ++i) {
|
t_assert(_connection == 0);
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MTPrpcError rpcClientError(const QString &type, const QString &description) {
|
MTPrpcError rpcClientError(const QString &type, const QString &description) {
|
||||||
|
@ -222,9 +222,8 @@ class MTProtoSession : public QObject {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MTProtoSession();
|
MTProtoSession(int32 dcenter);
|
||||||
|
|
||||||
void start(int32 dcenter = 0);
|
|
||||||
void restart();
|
void restart();
|
||||||
void stop();
|
void stop();
|
||||||
void kill();
|
void kill();
|
||||||
@ -279,8 +278,7 @@ public slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef QList<MTProtoConnection*> MTProtoConnections;
|
MTProtoConnection *_connection;
|
||||||
MTProtoConnections connections;
|
|
||||||
|
|
||||||
bool _killed;
|
bool _killed;
|
||||||
bool _needToReceive;
|
bool _needToReceive;
|
||||||
@ -304,7 +302,3 @@ inline QReadWriteLock *MTPSessionData::keyMutex() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTPrpcError rpcClientError(const QString &type, const QString &description = QString());
|
MTPrpcError rpcClientError(const QString &type, const QString &description = QString());
|
||||||
|
|
||||||
// here
|
|
||||||
|
|
||||||
typedef QSharedPointer<MTProtoSession> MTProtoSessionPtr;
|
|
||||||
|
@ -38,10 +38,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||||||
|
|
||||||
namespace PlatformSpecific {
|
namespace PlatformSpecific {
|
||||||
|
|
||||||
struct Initializer {
|
void start();
|
||||||
Initializer();
|
void finish();
|
||||||
~Initializer();
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
void start();
|
void start();
|
||||||
|
@ -1237,10 +1237,10 @@ void psShowInFolder(const QString &name) {
|
|||||||
|
|
||||||
namespace PlatformSpecific {
|
namespace PlatformSpecific {
|
||||||
|
|
||||||
Initializer::Initializer() {
|
void start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer::~Initializer() {
|
void finish() {
|
||||||
delete _psEventFilter;
|
delete _psEventFilter;
|
||||||
_psEventFilter = 0;
|
_psEventFilter = 0;
|
||||||
}
|
}
|
||||||
|
@ -850,11 +850,11 @@ void psShowInFolder(const QString &name) {
|
|||||||
|
|
||||||
namespace PlatformSpecific {
|
namespace PlatformSpecific {
|
||||||
|
|
||||||
Initializer::Initializer() {
|
void start() {
|
||||||
objc_start();
|
objc_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer::~Initializer() {
|
void finish() {
|
||||||
delete _psEventFilter;
|
delete _psEventFilter;
|
||||||
_psEventFilter = 0;
|
_psEventFilter = 0;
|
||||||
|
|
||||||
|
@ -2159,10 +2159,10 @@ void psShowInFolder(const QString &name) {
|
|||||||
|
|
||||||
namespace PlatformSpecific {
|
namespace PlatformSpecific {
|
||||||
|
|
||||||
Initializer::Initializer() {
|
void start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer::~Initializer() {
|
void finish() {
|
||||||
delete _psEventFilter;
|
delete _psEventFilter;
|
||||||
_psEventFilter = 0;
|
_psEventFilter = 0;
|
||||||
|
|
||||||
|
@ -77,7 +77,6 @@ inline QString cInlineGifBotUsername() {
|
|||||||
return cTestMode() ? qstr("contextbot") : qstr("gif");
|
return cTestMode() ? qstr("contextbot") : qstr("gif");
|
||||||
}
|
}
|
||||||
DeclareSetting(QString, LoggedPhoneNumber);
|
DeclareSetting(QString, LoggedPhoneNumber);
|
||||||
DeclareReadSetting(uint32, ConnectionsInSession);
|
|
||||||
DeclareSetting(bool, AutoStart);
|
DeclareSetting(bool, AutoStart);
|
||||||
DeclareSetting(bool, StartMinimized);
|
DeclareSetting(bool, StartMinimized);
|
||||||
DeclareSetting(bool, StartInTray);
|
DeclareSetting(bool, StartInTray);
|
||||||
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,9,28,1
|
FILEVERSION 0,9,28,2
|
||||||
PRODUCTVERSION 0,9,28,1
|
PRODUCTVERSION 0,9,28,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -51,10 +51,10 @@ BEGIN
|
|||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.9.28.1"
|
VALUE "FileVersion", "0.9.28.2"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.9.28.1"
|
VALUE "ProductVersion", "0.9.28.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -3,4 +3,4 @@ AppVersionStrMajor 0.9
|
|||||||
AppVersionStrSmall 0.9.28
|
AppVersionStrSmall 0.9.28
|
||||||
AppVersionStr 0.9.28
|
AppVersionStr 0.9.28
|
||||||
DevChannel 0
|
DevChannel 0
|
||||||
BetaVersion 9028001
|
BetaVersion 9028002
|
||||||
|
Loading…
Reference in New Issue
Block a user