mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 09:41:41 -05:00
Hook main queue processing to update requests.
This commit is contained in:
parent
b1807938ad
commit
0e964b06dc
8 changed files with 100 additions and 48 deletions
|
@ -8,73 +8,101 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/main_queue_processor.h"
|
||||
|
||||
#include "core/sandbox.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
namespace Core {
|
||||
namespace {
|
||||
|
||||
QMutex ProcessorMutex;
|
||||
MainQueueProcessor *ProcessorInstance/* = nullptr*/;
|
||||
|
||||
constexpr auto kProcessorEvent = QEvent::Type(QEvent::User + 1);
|
||||
static_assert(kProcessorEvent < QEvent::MaxUser);
|
||||
|
||||
class ProcessorEvent : public QEvent {
|
||||
public:
|
||||
ProcessorEvent(void (*callable)(void*), void *argument);
|
||||
|
||||
void process();
|
||||
|
||||
private:
|
||||
void (*_callable)(void*) = nullptr;
|
||||
void *_argument = nullptr;
|
||||
QMutex ProcessorMutex;
|
||||
MainQueueProcessor *ProcessorInstance/* = nullptr*/;
|
||||
|
||||
enum class ProcessState : int {
|
||||
Processed,
|
||||
FillingUp,
|
||||
Waiting,
|
||||
};
|
||||
|
||||
ProcessorEvent::ProcessorEvent(void (*callable)(void*), void *argument)
|
||||
: QEvent(kProcessorEvent)
|
||||
, _callable(callable)
|
||||
, _argument(argument) {
|
||||
std::atomic<ProcessState> MainQueueProcessState/* = ProcessState(0)*/;
|
||||
void (*MainQueueProcessCallback)(void*)/* = nullptr*/;
|
||||
void *MainQueueProcessArgument/* = nullptr*/;
|
||||
|
||||
void PushToMainQueueGeneric(void (*callable)(void*), void *argument) {
|
||||
Expects(Platform::UseMainQueueGeneric());
|
||||
|
||||
auto expected = ProcessState::Processed;
|
||||
const auto fill = MainQueueProcessState.compare_exchange_strong(
|
||||
expected,
|
||||
ProcessState::FillingUp);
|
||||
if (fill) {
|
||||
MainQueueProcessCallback = callable;
|
||||
MainQueueProcessArgument = argument;
|
||||
MainQueueProcessState.store(ProcessState::Waiting);
|
||||
}
|
||||
|
||||
auto event = std::make_unique<QEvent>(kProcessorEvent);
|
||||
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
if (ProcessorInstance) {
|
||||
QApplication::postEvent(ProcessorInstance, event.release());
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessorEvent::process() {
|
||||
_callable(_argument);
|
||||
}
|
||||
void DrainMainQueueGeneric() {
|
||||
Expects(Platform::UseMainQueueGeneric());
|
||||
|
||||
void ProcessObservables() {
|
||||
Global::RefHandleObservables().call();
|
||||
if (MainQueueProcessState.load() != ProcessState::Waiting) {
|
||||
return;
|
||||
}
|
||||
const auto callback = MainQueueProcessCallback;
|
||||
const auto argument = MainQueueProcessArgument;
|
||||
MainQueueProcessState.store(ProcessState::Processed);
|
||||
|
||||
callback(argument);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MainQueueProcessor::MainQueueProcessor() {
|
||||
acquire();
|
||||
|
||||
crl::init_main_queue([](void (*callable)(void*), void *argument) {
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
|
||||
if (ProcessorInstance) {
|
||||
const auto event = new ProcessorEvent(callable, argument);
|
||||
QApplication::postEvent(ProcessorInstance, event);
|
||||
}
|
||||
});
|
||||
crl::wrap_main_queue([](void (*callable)(void*), void *argument) {
|
||||
Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
callable(argument);
|
||||
if constexpr (Platform::UseMainQueueGeneric()) {
|
||||
acquire();
|
||||
crl::init_main_queue(PushToMainQueueGeneric);
|
||||
} else {
|
||||
crl::wrap_main_queue([](void (*callable)(void*), void *argument) {
|
||||
Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
callable(argument);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
base::InitObservables(ProcessObservables);
|
||||
Core::Sandbox::Instance().widgetUpdateRequests(
|
||||
) | rpl::start_with_next([] {
|
||||
if constexpr (Platform::UseMainQueueGeneric()) {
|
||||
DrainMainQueueGeneric();
|
||||
} else {
|
||||
Platform::DrainMainQueue();
|
||||
}
|
||||
}, _lifetime);
|
||||
|
||||
base::InitObservables([] {
|
||||
Global::RefHandleObservables().call();
|
||||
});
|
||||
}
|
||||
|
||||
bool MainQueueProcessor::event(QEvent *event) {
|
||||
if (event->type() == kProcessorEvent) {
|
||||
static_cast<ProcessorEvent*>(event)->process();
|
||||
return true;
|
||||
if constexpr (Platform::UseMainQueueGeneric()) {
|
||||
if (event->type() == kProcessorEvent) {
|
||||
DrainMainQueueGeneric();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::event(event);
|
||||
}
|
||||
|
||||
void MainQueueProcessor::acquire() {
|
||||
Expects(Platform::UseMainQueueGeneric());
|
||||
Expects(ProcessorInstance == nullptr);
|
||||
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
|
@ -82,6 +110,7 @@ void MainQueueProcessor::acquire() {
|
|||
}
|
||||
|
||||
void MainQueueProcessor::release() {
|
||||
Expects(Platform::UseMainQueueGeneric());
|
||||
Expects(ProcessorInstance == this);
|
||||
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
|
@ -89,7 +118,9 @@ void MainQueueProcessor::release() {
|
|||
}
|
||||
|
||||
MainQueueProcessor::~MainQueueProcessor() {
|
||||
release();
|
||||
if constexpr (Platform::UseMainQueueGeneric()) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -21,6 +21,8 @@ private:
|
|||
void acquire();
|
||||
void release();
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -503,14 +503,6 @@ bool Sandbox::notify(QObject *receiver, QEvent *e) {
|
|||
const auto type = e->type();
|
||||
if (type == QEvent::UpdateRequest) {
|
||||
_widgetUpdateRequests.fire({});
|
||||
// Profiling.
|
||||
//const auto time = crl::now();
|
||||
//LOG(("[%1] UPDATE STARTED").arg(time));
|
||||
//const auto guard = gsl::finally([&] {
|
||||
// const auto now = crl::now();
|
||||
// LOG(("[%1] UPDATE FINISHED (%2)").arg(now).arg(now - time));
|
||||
//});
|
||||
//return QApplication::notify(receiver, e);
|
||||
}
|
||||
return QApplication::notify(receiver, e);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
@ -39,6 +41,10 @@ inline std::optional<crl::time> LastUserInputTime() {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline constexpr bool UseMainQueueGeneric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
inline QString psServerPrefix() {
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
#include "platform/mac/specific_mac_p.h"
|
||||
|
||||
namespace Data {
|
||||
|
@ -23,6 +24,10 @@ QString CurrentExecutablePath(int argc, char *argv[]);
|
|||
|
||||
void RemoveQuarantine(const QString &path);
|
||||
|
||||
inline constexpr bool UseMainQueueGeneric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
inline void start() {
|
||||
|
|
|
@ -29,6 +29,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <mach-o/dyld.h>
|
||||
#include <AVFoundation/AVFoundation.h>
|
||||
|
||||
extern "C" {
|
||||
void _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg);
|
||||
} // extern "C"
|
||||
|
||||
namespace {
|
||||
|
||||
QStringList _initLogs;
|
||||
|
@ -139,6 +143,10 @@ void RemoveQuarantine(const QString &path) {
|
|||
removexattr(local.data(), kQuarantineAttribute, 0);
|
||||
}
|
||||
|
||||
void DrainMainQueue() {
|
||||
_dispatch_main_queue_callback_4CF(nullptr);
|
||||
}
|
||||
|
||||
void RegisterCustomScheme() {
|
||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
|
||||
|
|
|
@ -45,6 +45,9 @@ bool OpenSystemSettings(SystemSettingsType type);
|
|||
return LastUserInputTime().has_value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool UseMainQueueGeneric();
|
||||
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
void start();
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
#include "platform/win/wrapper_windows_h.h"
|
||||
|
||||
namespace Data {
|
||||
|
@ -38,6 +39,10 @@ inline void ReInitOnTopPanel(QWidget *panel) {
|
|||
|
||||
QString CurrentExecutablePath(int argc, char *argv[]);
|
||||
|
||||
inline constexpr bool UseMainQueueGeneric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
void start();
|
||||
|
|
Loading…
Add table
Reference in a new issue