Main thread deadlock detector for debug mode

This commit is contained in:
Ilya Fedin 2023-08-21 03:21:30 +04:00 committed by John Preston
parent d10b7e8402
commit ff9321e971
4 changed files with 98 additions and 0 deletions

View File

@ -413,6 +413,7 @@ PRIVATE
core/crash_report_window.h
core/crash_reports.cpp
core/crash_reports.h
core/deadlock_detector.h
core/file_utilities.cpp
core/file_utilities.h
core/launcher.cpp

View File

@ -0,0 +1,83 @@
/*
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
namespace Core::DeadlockDetector {
class PingPongEvent : public QEvent {
public:
static auto Type() {
static const auto Result = QEvent::Type(QEvent::registerEventType());
return Result;
}
PingPongEvent(not_null<QObject*> sender)
: QEvent(Type())
, _sender(sender) {
}
[[nodiscard]] not_null<QObject*> sender() const {
return _sender;
}
private:
not_null<QObject*> _sender;
};
class Pinger : public QObject {
public:
Pinger(not_null<QObject*> receiver)
: _receiver(receiver)
, _abortTimer([] { Unexpected("Deadlock found!"); }) {
const auto callback = [=] {
QCoreApplication::postEvent(_receiver, new PingPongEvent(this));
_abortTimer.callOnce(30000);
};
_pingTimer.setCallback(callback);
_pingTimer.callEach(60000);
callback();
}
protected:
bool event(QEvent *e) override {
if (e->type() == PingPongEvent::Type()
&& static_cast<PingPongEvent*>(e)->sender() == _receiver) {
_abortTimer.cancel();
}
return QObject::event(e);
}
private:
not_null<QObject*> _receiver;
base::Timer _pingTimer;
base::Timer _abortTimer;
};
class PingThread : public QThread {
public:
PingThread(not_null<QObject*> parent)
: QThread(parent) {
start();
}
~PingThread() {
quit();
wait();
}
protected:
void run() override {
Pinger pinger(parent());
QThread::run();
}
};
} // namespace Core::DeadlockDetector

View File

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/launcher.h"
#include "core/local_url_handlers.h"
#include "core/update_checker.h"
#include "core/deadlock_detector.h"
#include "base/timer.h"
#include "base/concurrent_timer.h"
#include "base/invoke_queued.h"
@ -198,6 +199,13 @@ void Sandbox::launchApplication() {
}
setupScreenScale();
#ifndef _DEBUG
if (Logs::DebugEnabled()) {
using DeadlockDetector::PingThread;
_deadlockDetector = std::make_unique<PingThread>(this);
}
#endif // !_DEBUG
_application = std::make_unique<Application>();
// Ideally this should go to constructor.
@ -267,6 +275,10 @@ bool Sandbox::event(QEvent *e) {
return false;
} else if (e->type() == QEvent::Close) {
Quit();
} else if (e->type() == DeadlockDetector::PingPongEvent::Type()) {
postEvent(
static_cast<DeadlockDetector::PingPongEvent*>(e)->sender(),
new DeadlockDetector::PingPongEvent(this));
}
return QApplication::event(e);
}

View File

@ -131,6 +131,8 @@ private:
rpl::event_stream<> _widgetUpdateRequests;
std::unique_ptr<QThread> _deadlockDetector;
};
} // namespace Core