From 35dccb103886064a8880773eae21378980462d7a Mon Sep 17 00:00:00 2001 From: Anton Samokhvalov Date: Wed, 29 Dec 2021 13:29:43 +0300 Subject: [PATCH 1/4] in_avail() can always be zero, it is a optimization opportunity only --- src/btop.cpp | 9 +++--- src/btop_input.cpp | 71 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/btop.cpp b/src/btop.cpp index 06dc42f..ac49a7e 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -17,6 +17,7 @@ tab-size = 4 */ #include +#include #include #include #include @@ -237,14 +238,14 @@ void clean_quit(int sig) { } Logger::info("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); + const auto excode = (sig != -1 ? sig : 0); + //? Assume error if still not cleaned up and call quick_exit to avoid a segfault from Tools::atomic_lock destructor #ifndef __APPLE__ - if (Tools::active_locks > 0) { - quick_exit((sig != -1 ? sig : 0)); - } + quick_exit(excode); #endif - if (sig != -1) exit(sig); + exit(excode); } //* Handler for SIGTSTP; stops threads, restores terminal and sends SIGSTOP diff --git a/src/btop_input.cpp b/src/btop_input.cpp index 0fe5b9d..85ba644 100644 --- a/src/btop_input.cpp +++ b/src/btop_input.cpp @@ -19,6 +19,8 @@ tab-size = 4 #include #include #include +#include +#include #include #include @@ -78,14 +80,66 @@ namespace Input { deque history(50, ""); string old_filter; + struct InputThr { + InputThr() : thr(run, this) { + } + + static void run(InputThr* that) { + that->runImpl(); + } + + void runImpl() { + char ch = 0; + + // TODO(pg83): read whole buffer + while (cin.get(ch)) { + std::lock_guard g(lock); + current.push_back(ch); + if (current.size() > 100) { + current.clear(); + } + } + } + + size_t avail() { + std::lock_guard g(lock); + + return current.size(); + } + + std::string get() { + std::string res; + + { + std::lock_guard g(lock); + + res.swap(current); + } + + return res; + } + + static InputThr& instance() { + // intentional memory leak, to simplify shutdown process + static InputThr* input = new InputThr(); + + return *input; + } + + std::string current; + // TODO(pg83): use std::conditional_variable instead of sleep + std::mutex lock; + std::thread thr; + }; + bool poll(int timeout) { - if (timeout < 1) return cin.rdbuf()->in_avail() > 0; + if (timeout < 1) return InputThr::instance().avail() > 0; while (timeout > 0) { if (interrupt) { interrupt = false; return false; } - if (cin.rdbuf()->in_avail() > 0) return true; + if (InputThr::instance().avail() > 0) return true; sleep_ms(timeout < 10 ? timeout : 10); timeout -= 10; } @@ -93,9 +147,7 @@ namespace Input { } string get() { - string key; - while (cin.rdbuf()->in_avail() > 0 and key.size() < 100) key += cin.get(); - if (cin.rdbuf()->in_avail() > 0) clear(); + string key = InputThr::instance().get(); if (not key.empty()) { //? Remove escape code prefix if present if (key.substr(0, 2) == Fx::e) { @@ -168,19 +220,14 @@ namespace Input { } string wait() { - while (cin.rdbuf()->in_avail() < 1) { + while (InputThr::instance().avail() < 1) { sleep_ms(10); } return get(); } void clear() { - if (auto first_num = cin.rdbuf()->in_avail(); first_num > 0) { - while (cin.rdbuf()->in_avail() == first_num) { - if (first_num-- <= 0) break; - cin.ignore(1); - } - } + // do not need it, actually } void process(const string& key) { From fe66d52a38bbc65703482db4fcfca7300d6953d9 Mon Sep 17 00:00:00 2001 From: Anton Samokhvalov Date: Wed, 29 Dec 2021 15:23:37 +0300 Subject: [PATCH 2/4] no memory leak --- src/btop.cpp | 10 +++++----- src/btop_input.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/btop.cpp b/src/btop.cpp index ac49a7e..48884ba 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -237,15 +237,15 @@ void clean_quit(int sig) { std::cerr << Global::fg_red << "ERROR: " << Global::fg_white << Global::exit_error_msg << Fx::reset << endl; } Logger::info("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); - - const auto excode = (sig != -1 ? sig : 0); - + close(0); //? Assume error if still not cleaned up and call quick_exit to avoid a segfault from Tools::atomic_lock destructor #ifndef __APPLE__ - quick_exit(excode); + if (Tools::active_locks > 0) { + quick_exit((sig != -1 ? sig : 0)); + } #endif - exit(excode); + if (sig != -1) exit(sig); } //* Handler for SIGTSTP; stops threads, restores terminal and sends SIGSTOP diff --git a/src/btop_input.cpp b/src/btop_input.cpp index 85ba644..7a8d910 100644 --- a/src/btop_input.cpp +++ b/src/btop_input.cpp @@ -82,10 +82,14 @@ namespace Input { struct InputThr { InputThr() : thr(run, this) { + thr.detach(); } static void run(InputThr* that) { - that->runImpl(); + try { + that->runImpl(); + } catch (...) {} + delete that; } void runImpl() { @@ -120,7 +124,6 @@ namespace Input { } static InputThr& instance() { - // intentional memory leak, to simplify shutdown process static InputThr* input = new InputThr(); return *input; From c1f540e61e5294a151dd6591a7533374fd2abce5 Mon Sep 17 00:00:00 2001 From: Anton Samokhvalov Date: Wed, 29 Dec 2021 15:46:15 +0300 Subject: [PATCH 3/4] Revert "no memory leak" This reverts commit fe66d52a38bbc65703482db4fcfca7300d6953d9. --- src/btop.cpp | 10 +++++----- src/btop_input.cpp | 7 ++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/btop.cpp b/src/btop.cpp index 48884ba..ac49a7e 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -237,15 +237,15 @@ void clean_quit(int sig) { std::cerr << Global::fg_red << "ERROR: " << Global::fg_white << Global::exit_error_msg << Fx::reset << endl; } Logger::info("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); - close(0); + + const auto excode = (sig != -1 ? sig : 0); + //? Assume error if still not cleaned up and call quick_exit to avoid a segfault from Tools::atomic_lock destructor #ifndef __APPLE__ - if (Tools::active_locks > 0) { - quick_exit((sig != -1 ? sig : 0)); - } + quick_exit(excode); #endif - if (sig != -1) exit(sig); + exit(excode); } //* Handler for SIGTSTP; stops threads, restores terminal and sends SIGSTOP diff --git a/src/btop_input.cpp b/src/btop_input.cpp index 7a8d910..85ba644 100644 --- a/src/btop_input.cpp +++ b/src/btop_input.cpp @@ -82,14 +82,10 @@ namespace Input { struct InputThr { InputThr() : thr(run, this) { - thr.detach(); } static void run(InputThr* that) { - try { - that->runImpl(); - } catch (...) {} - delete that; + that->runImpl(); } void runImpl() { @@ -124,6 +120,7 @@ namespace Input { } static InputThr& instance() { + // intentional memory leak, to simplify shutdown process static InputThr* input = new InputThr(); return *input; From 9faeeabda5132e05c5d9b31658fe8faf629e3621 Mon Sep 17 00:00:00 2001 From: Anton Samokhvalov Date: Wed, 29 Dec 2021 15:47:48 +0300 Subject: [PATCH 4/4] quick_exit for Darwin --- src/btop.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/btop.cpp b/src/btop.cpp index ac49a7e..494418f 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -241,11 +241,11 @@ void clean_quit(int sig) { const auto excode = (sig != -1 ? sig : 0); //? Assume error if still not cleaned up and call quick_exit to avoid a segfault from Tools::atomic_lock destructor -#ifndef __APPLE__ +#ifdef __APPLE__ + _Exit(excode); +#else quick_exit(excode); #endif - - exit(excode); } //* Handler for SIGTSTP; stops threads, restores terminal and sends SIGSTOP