 46ee5598f5
			
		
	
	
		46ee5598f5
		
	
	
	
	
		
			
			Commit bdc7f4114f got rid of
_timeouter's callback without removing the timer that still fires
every second.
		
	
			
		
			
				
	
	
		
			221 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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 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
 |