init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
222
Telegram/SourceFiles/mtproto/session.h
Normal file
222
Telegram/SourceFiles/mtproto/session.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "mtproto/mtproto_response.h"
|
||||
#include "mtproto/mtproto_proxy_data.h"
|
||||
#include "mtproto/details/mtproto_serialized_request.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
namespace MTP {
|
||||
|
||||
class Instance;
|
||||
class AuthKey;
|
||||
using AuthKeyPtr = std::shared_ptr<AuthKey>;
|
||||
enum class DcType;
|
||||
|
||||
namespace details {
|
||||
|
||||
class Dcenter;
|
||||
class SessionPrivate;
|
||||
|
||||
enum class TemporaryKeyType;
|
||||
enum class CreatingKeyType;
|
||||
|
||||
struct SessionOptions {
|
||||
SessionOptions() = default;
|
||||
SessionOptions(
|
||||
const QString &systemLangCode,
|
||||
const QString &cloudLangCode,
|
||||
const QString &langPackName,
|
||||
const ProxyData &proxy,
|
||||
bool useIPv4,
|
||||
bool useIPv6,
|
||||
bool useHttp,
|
||||
bool useTcp);
|
||||
|
||||
QString systemLangCode;
|
||||
QString cloudLangCode;
|
||||
QString langPackName;
|
||||
ProxyData proxy;
|
||||
bool useIPv4 = true;
|
||||
bool useIPv6 = true;
|
||||
bool useHttp = true;
|
||||
bool useTcp = true;
|
||||
|
||||
};
|
||||
|
||||
class Session;
|
||||
class SessionData final {
|
||||
public:
|
||||
explicit SessionData(not_null<Session*> creator) : _owner(creator) {
|
||||
}
|
||||
|
||||
void notifyConnectionInited(const SessionOptions &options);
|
||||
void setOptions(SessionOptions options) {
|
||||
QWriteLocker locker(&_optionsLock);
|
||||
_options = options;
|
||||
}
|
||||
[[nodiscard]] SessionOptions options() const {
|
||||
QReadLocker locker(&_optionsLock);
|
||||
return _options;
|
||||
}
|
||||
|
||||
not_null<QReadWriteLock*> toSendMutex() {
|
||||
return &_toSendLock;
|
||||
}
|
||||
not_null<QReadWriteLock*> haveSentMutex() {
|
||||
return &_haveSentLock;
|
||||
}
|
||||
not_null<QReadWriteLock*> haveReceivedMutex() {
|
||||
return &_haveReceivedLock;
|
||||
}
|
||||
|
||||
base::flat_map<mtpRequestId, SerializedRequest> &toSendMap() {
|
||||
return _toSend;
|
||||
}
|
||||
base::flat_map<mtpMsgId, SerializedRequest> &haveSentMap() {
|
||||
return _haveSent;
|
||||
}
|
||||
std::vector<Response> &haveReceivedMessages() {
|
||||
return _receivedMessages;
|
||||
}
|
||||
|
||||
// SessionPrivate -> Session interface.
|
||||
void queueTryToReceive();
|
||||
void queueNeedToResumeAndSend();
|
||||
void queueConnectionStateChange(int newState);
|
||||
void queueResetDone();
|
||||
void queueSendAnything(crl::time msCanWait = 0);
|
||||
|
||||
[[nodiscard]] bool connectionInited() const;
|
||||
[[nodiscard]] AuthKeyPtr getPersistentKey() const;
|
||||
[[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const;
|
||||
[[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type);
|
||||
[[nodiscard]] bool releaseKeyCreationOnDone(
|
||||
const AuthKeyPtr &temporaryKey,
|
||||
const AuthKeyPtr &persistentKeyUsedForBind);
|
||||
[[nodiscard]] bool releaseCdnKeyCreationOnDone(
|
||||
const AuthKeyPtr &temporaryKey);
|
||||
void releaseKeyCreationOnFail();
|
||||
void destroyTemporaryKey(uint64 keyId);
|
||||
|
||||
void detach();
|
||||
|
||||
private:
|
||||
template <typename Callback>
|
||||
void withSession(Callback &&callback);
|
||||
|
||||
Session *_owner = nullptr;
|
||||
mutable QMutex _ownerMutex;
|
||||
|
||||
SessionOptions _options;
|
||||
mutable QReadWriteLock _optionsLock;
|
||||
|
||||
base::flat_map<mtpRequestId, SerializedRequest> _toSend; // map of request_id -> request, that is waiting to be sent
|
||||
QReadWriteLock _toSendLock;
|
||||
|
||||
base::flat_map<mtpMsgId, SerializedRequest> _haveSent; // map of msg_id -> request, that was sent
|
||||
QReadWriteLock _haveSentLock;
|
||||
|
||||
std::vector<Response> _receivedMessages; // list of responses / updates that should be processed in the main thread
|
||||
QReadWriteLock _haveReceivedLock;
|
||||
|
||||
};
|
||||
|
||||
class Session final : public QObject {
|
||||
public:
|
||||
// Main thread.
|
||||
Session(
|
||||
not_null<Instance*> instance,
|
||||
not_null<QThread*> thread,
|
||||
ShiftedDcId shiftedDcId,
|
||||
not_null<Dcenter*> dc);
|
||||
~Session();
|
||||
|
||||
void start();
|
||||
void reInitConnection();
|
||||
void setConnectionNotInited();
|
||||
|
||||
void restart();
|
||||
void refreshOptions();
|
||||
void stop();
|
||||
void kill();
|
||||
|
||||
void unpaused();
|
||||
|
||||
// Thread-safe.
|
||||
[[nodiscard]] ShiftedDcId getDcWithShift() const;
|
||||
[[nodiscard]] AuthKeyPtr getPersistentKey() const;
|
||||
[[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const;
|
||||
[[nodiscard]] bool connectionInited() const;
|
||||
void sendPrepared(
|
||||
const SerializedRequest &request,
|
||||
crl::time msCanWait = 0);
|
||||
|
||||
// SessionPrivate thread.
|
||||
[[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type);
|
||||
[[nodiscard]] bool releaseKeyCreationOnDone(
|
||||
const AuthKeyPtr &temporaryKey,
|
||||
const AuthKeyPtr &persistentKeyUsedForBind);
|
||||
[[nodiscard]] bool releaseCdnKeyCreationOnDone(const AuthKeyPtr &temporaryKey);
|
||||
void releaseKeyCreationOnFail();
|
||||
void destroyTemporaryKey(uint64 keyId);
|
||||
|
||||
void notifyDcConnectionInited();
|
||||
|
||||
void ping();
|
||||
void cancel(mtpRequestId requestId, mtpMsgId msgId);
|
||||
int requestState(mtpRequestId requestId) const;
|
||||
int getState() const;
|
||||
QString transport() const;
|
||||
|
||||
void tryToReceive();
|
||||
void needToResumeAndSend();
|
||||
void connectionStateChange(int newState);
|
||||
void resetDone();
|
||||
void sendAnything(crl::time msCanWait = 0);
|
||||
|
||||
private:
|
||||
void watchDcKeyChanges();
|
||||
void watchDcOptionsChanges();
|
||||
|
||||
void killConnection();
|
||||
|
||||
[[nodiscard]] bool releaseGenericKeyCreationOnDone(
|
||||
const AuthKeyPtr &temporaryKey,
|
||||
const AuthKeyPtr &persistentKeyUsedForBind);
|
||||
|
||||
const not_null<Instance*> _instance;
|
||||
const ShiftedDcId _shiftedDcId = 0;
|
||||
const not_null<Dcenter*> _dc;
|
||||
const std::shared_ptr<SessionData> _data;
|
||||
const not_null<QThread*> _thread;
|
||||
|
||||
SessionPrivate *_private = nullptr;
|
||||
|
||||
bool _killed = false;
|
||||
bool _needToReceive = false;
|
||||
|
||||
AuthKeyPtr _dcKeyForCheck;
|
||||
CreatingKeyType _myKeyCreation = CreatingKeyType();
|
||||
|
||||
crl::time _msSendCall = 0;
|
||||
crl::time _msWait = 0;
|
||||
|
||||
bool _ping = false;
|
||||
|
||||
base::Timer _sender;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace MTP
|
||||
Reference in New Issue
Block a user