mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
GUI/TTY: fix UI deadlock when TTY is being spammed
This commit is contained in:
parent
01c285fc4a
commit
00340f33c3
@ -5,6 +5,7 @@
|
|||||||
#include "rpcs3_version.h"
|
#include "rpcs3_version.h"
|
||||||
#include "Utilities/mutex.h"
|
#include "Utilities/mutex.h"
|
||||||
#include "Utilities/lockless.h"
|
#include "Utilities/lockless.h"
|
||||||
|
#include "util/asm.hpp"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
@ -510,22 +511,25 @@ void log_frame::UpdateUI()
|
|||||||
const std::chrono::time_point log_timeout = start + 7ms;
|
const std::chrono::time_point log_timeout = start + 7ms;
|
||||||
|
|
||||||
// Check TTY logs
|
// Check TTY logs
|
||||||
while (const u64 size = std::max<s64>(0, g_tty_size.load() - (m_tty_file ? m_tty_file.pos() : 0)))
|
if (u64 size = std::max<s64>(0, m_tty_file ? (g_tty_size.load() - m_tty_file.pos()) : 0))
|
||||||
{
|
{
|
||||||
std::string buf;
|
if (m_tty_act->isChecked())
|
||||||
buf.resize(size);
|
|
||||||
buf.resize(m_tty_file.read(&buf.front(), buf.size()));
|
|
||||||
|
|
||||||
// Ignore control characters and greater/equal to 0x80
|
|
||||||
buf.erase(std::remove_if(buf.begin(), buf.end(), [](s8 c) { return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F); }), buf.end());
|
|
||||||
|
|
||||||
if (!buf.empty() && m_tty_act->isChecked())
|
|
||||||
{
|
{
|
||||||
std::stringstream buf_stream;
|
m_tty_buf.resize(std::min<u64>(size, m_tty_limited_read ? m_tty_limited_read : usz{umax}));
|
||||||
buf_stream.str(buf);
|
m_tty_buf.resize(m_tty_file.read(&m_tty_buf.front(), m_tty_buf.size()));
|
||||||
|
m_tty_limited_read = 0;
|
||||||
|
|
||||||
|
usz str_index = 0;
|
||||||
std::string buf_line;
|
std::string buf_line;
|
||||||
while (std::getline(buf_stream, buf_line))
|
|
||||||
|
while (str_index < m_tty_buf.size())
|
||||||
{
|
{
|
||||||
|
buf_line = m_tty_buf.substr(str_index, m_tty_buf.find_first_of('\n'));
|
||||||
|
str_index += buf_line.size() + 1;
|
||||||
|
|
||||||
|
// Ignore control characters and greater/equal to 0x80
|
||||||
|
buf_line.erase(std::remove_if(buf_line.begin(), buf_line.end(), [](s8 c) { return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F); }), buf_line.end());
|
||||||
|
|
||||||
// save old scroll bar state
|
// save old scroll bar state
|
||||||
QScrollBar* sb = m_tty->verticalScrollBar();
|
QScrollBar* sb = m_tty->verticalScrollBar();
|
||||||
const int sb_pos = sb->value();
|
const int sb_pos = sb->value();
|
||||||
@ -582,11 +586,44 @@ void log_frame::UpdateUI()
|
|||||||
|
|
||||||
// set scrollbar to max means auto-scroll
|
// set scrollbar to max means auto-scroll
|
||||||
sb->setValue(is_max ? sb->maximum() : sb_pos);
|
sb->setValue(is_max ? sb->maximum() : sb_pos);
|
||||||
|
|
||||||
|
// Limit processing time
|
||||||
|
if (steady_clock::now() >= tty_timeout)
|
||||||
|
{
|
||||||
|
const s64 back = ::narrow<s64>(str_index) - ::narrow<s64>(m_tty_buf.size());
|
||||||
|
ensure(back <= 1);
|
||||||
|
|
||||||
|
if (back < 0)
|
||||||
|
{
|
||||||
|
// If more than two thirds of the buffer are unprocessed make the next fs::file::read read only that
|
||||||
|
// This is because reading is also costly on performance, and if we already know half of that takes more time than our limit..
|
||||||
|
const usz third_size = utils::aligned_div(m_tty_buf.size(), 3);
|
||||||
|
|
||||||
|
if (back <= -16384 && static_cast<usz>(0 - back) >= third_size * 2)
|
||||||
|
{
|
||||||
|
// This only really works if there is a newline somewhere
|
||||||
|
const usz known_term = std::string_view(m_tty_buf).substr(str_index, str_index * 2).find_last_of('\n', str_index * 2 - 4096);
|
||||||
|
|
||||||
|
if (known_term != umax)
|
||||||
|
{
|
||||||
|
m_tty_limited_read = known_term + 1 - str_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revert unprocessed reads
|
||||||
|
m_tty_file.seek(back, fs::seek_cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// Limit processing time
|
{
|
||||||
if (steady_clock::now() >= tty_timeout || buf.empty()) break;
|
// Advance in position without printing
|
||||||
|
m_tty_file.seek(size, fs::seek_cur);
|
||||||
|
m_tty_limited_read = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto font_start_tag = [](const QColor& color) -> const QString { return QStringLiteral("<font color = \"") % color.name() % QStringLiteral("\">"); };
|
const auto font_start_tag = [](const QColor& color) -> const QString { return QStringLiteral("<font color = \"") % color.name() % QStringLiteral("\">"); };
|
||||||
|
@ -54,6 +54,8 @@ private:
|
|||||||
std::string m_old_log_text;
|
std::string m_old_log_text;
|
||||||
QString m_old_tty_text;
|
QString m_old_tty_text;
|
||||||
QString m_log_text;
|
QString m_log_text;
|
||||||
|
std::string m_tty_buf;
|
||||||
|
usz m_tty_limited_read = 0;
|
||||||
usz m_log_counter{};
|
usz m_log_counter{};
|
||||||
usz m_tty_counter{};
|
usz m_tty_counter{};
|
||||||
bool m_stack_log{};
|
bool m_stack_log{};
|
||||||
|
Loading…
Reference in New Issue
Block a user