-
Notifications
You must be signed in to change notification settings - Fork 7.2k
Expand file tree
/
Copy pathsandbox.h
More file actions
155 lines (116 loc) · 3.96 KB
/
Copy pathsandbox.h
File metadata and controls
155 lines (116 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
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 "mtproto/mtproto_proxy_data.h"
#include <QtWidgets/QApplication>
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtCore/QAbstractNativeEventFilter>
class QLockFile;
namespace Core {
extern const char kOptionDeadlockDetector[];
class UpdateChecker;
class Application;
class Sandbox final
: public QApplication
, private QAbstractNativeEventFilter {
private:
auto createEventNestingLevel() {
incrementEventNestingLevel();
return gsl::finally([=] { decrementEventNestingLevel(); });
}
public:
Sandbox(int &argc, char **argv);
Sandbox(const Sandbox &other) = delete;
Sandbox &operator=(const Sandbox &other) = delete;
int start();
void refreshGlobalProxy();
void postponeCall(FnMut<void()> &&callable);
// Test-agent-only seam: runs every pending postponed call, and any
// calls they queue, regardless of loop-nesting tags. No-op without
// the -testagent switch. Call only from a top-level event context.
void drainPostponedCalls();
// Test-agent-only seam: while set, postponed calls queue but never
// run at event unwinds. The harness brackets synthetic dispatch with
// it and then drains explicitly. No-op without the -testagent switch.
void setPostponedCallsDeferred(bool deferred);
bool notify(QObject *receiver, QEvent *e) override;
template <typename Callable>
auto customEnterFromEventLoop(Callable &&callable) {
registerEnterFromEventLoop();
const auto wrap = createEventNestingLevel();
return callable();
}
rpl::producer<> widgetUpdateRequests() const;
MTP::ProxyData sandboxProxy() const;
static Sandbox &Instance() {
Expects(QCoreApplication::instance() != nullptr);
return *static_cast<Sandbox*>(QCoreApplication::instance());
}
static void QuitWhenStarted();
static void NotifySystemShuttingDown();
~Sandbox();
protected:
bool event(QEvent *e) override;
private:
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
typedef QList<LocalClient> LocalClients;
struct PostponedCall {
int loopNestingLevel = 0;
FnMut<void()> callable;
};
void closeApplication(); // will be done in aboutToQuit()
void checkForQuit(); // will be done in exec()
void checkForEmptyLoopNestingLevel();
void registerEnterFromEventLoop();
void incrementEventNestingLevel();
void decrementEventNestingLevel();
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
native_event_filter_result *result) override;
void processPostponedCalls(int level);
void singleInstanceChecked();
void launchApplication();
void setupScreenScale();
// Return window id for activation.
uint64 execExternal(const QString &cmd);
// Single instance application
void socketConnected();
void socketError(QLocalSocket::LocalSocketError e);
void socketDisconnected();
void socketWritten(qint64 bytes);
void socketReading();
void newInstanceConnected();
int stopRunningInstance();
void readClients();
void removeClients();
QEventLoopLocker _eventLoopLocker;
const Qt::HANDLE _mainThreadId = nullptr;
int _eventNestingLevel = 0;
int _loopNestingLevel = 0;
std::vector<int> _previousLoopNestingLevels;
std::vector<PostponedCall> _postponedCalls;
bool _postponedCallsDeferred = false;
std::unique_ptr<Application> _application;
QString _localServerName, _localSocketReadData;
QLocalServer _localServer;
QLocalSocket _localSocket;
LocalClients _localClients;
std::unique_ptr<QLockFile> _lockFile;
bool _secondInstance = false;
bool _started = false;
static bool QuitOnStartRequested;
static bool SystemShuttingDown;
std::unique_ptr<UpdateChecker> _updateChecker;
QByteArray _lastCrashDump;
MTP::ProxyData _sandboxProxy;
rpl::event_stream<> _widgetUpdateRequests;
std::unique_ptr<QThread> _deadlockDetector;
rpl::lifetime _lifetime;
};
} // namespace Core