summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob P. Liljenberg <admin@qvantnet.com>2024-01-03 17:05:24 +0100
committerGitHub <noreply@github.com>2024-01-03 17:05:24 +0100
commit6637485f0c284556d58e0b1017cedee28575ff57 (patch)
tree6a727f86d74303560491779ab227d4f8324487bd
parentff8352fdcdc08d32494b5873bb85164f2054825a (diff)
parent27c6f11e8063cf652ed42654b86e2dcde1d15795 (diff)
Merge branch 'main' into config-read-only
-rw-r--r--src/btop.cpp28
-rw-r--r--src/btop_input.cpp104
-rw-r--r--src/btop_input.hpp15
-rw-r--r--src/btop_tools.cpp9
4 files changed, 63 insertions, 93 deletions
diff --git a/src/btop.cpp b/src/btop.cpp
index 6908dfa..6a57240 100644
--- a/src/btop.cpp
+++ b/src/btop.cpp
@@ -176,7 +176,7 @@ void term_resize(bool force) {
static atomic<bool> resizing (false);
if (Input::polling) {
Global::resized = true;
- Input::interrupt = true;
+ Input::interrupt();
return;
}
atomic_lock lck(resizing, true);
@@ -246,7 +246,7 @@ void term_resize(bool force) {
else if (not Term::refresh()) break;
}
- Input::interrupt = true;
+ Input::interrupt();
}
//* Exit handler; stops threads, restores terminal and saves config changes
@@ -321,7 +321,7 @@ void _signal_handler(const int sig) {
if (Runner::active) {
Global::should_quit = true;
Runner::stopping = true;
- Input::interrupt = true;
+ Input::interrupt();
}
else {
clean_quit(0);
@@ -331,7 +331,7 @@ void _signal_handler(const int sig) {
if (Runner::active) {
Global::should_sleep = true;
Runner::stopping = true;
- Input::interrupt = true;
+ Input::interrupt();
}
else {
_sleep();
@@ -343,6 +343,9 @@ void _signal_handler(const int sig) {
case SIGWINCH:
term_resize();
break;
+ case SIGUSR1:
+ // Input::poll interrupt
+ break;
}
}
@@ -477,7 +480,7 @@ namespace Runner {
if (pt_lck.status != 0) {
Global::exit_error_msg = "Exception in runner thread -> pthread_mutex_lock error id: " + to_string(pt_lck.status);
Global::thread_exception = true;
- Input::interrupt = true;
+ Input::interrupt();
stopping = true;
}
@@ -488,7 +491,7 @@ namespace Runner {
if (active) {
Global::exit_error_msg = "Runner thread failed to get active lock!";
Global::thread_exception = true;
- Input::interrupt = true;
+ Input::interrupt();
stopping = true;
}
if (stopping or Global::resized) {
@@ -558,7 +561,7 @@ namespace Runner {
coreNum_reset = false;
Cpu::core_mapping = Cpu::get_core_mapping();
Global::resized = true;
- Input::interrupt = true;
+ Input::interrupt();
continue;
}
@@ -655,7 +658,7 @@ namespace Runner {
catch (const std::exception& e) {
Global::exit_error_msg = "Exception in runner thread -> " + string{e.what()};
Global::thread_exception = true;
- Input::interrupt = true;
+ Input::interrupt();
stopping = true;
}
@@ -1008,6 +1011,12 @@ int main(int argc, char **argv) {
std::signal(SIGTSTP, _signal_handler);
std::signal(SIGCONT, _signal_handler);
std::signal(SIGWINCH, _signal_handler);
+ std::signal(SIGUSR1, _signal_handler);
+
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGUSR1);
+ pthread_sigmask(SIG_BLOCK, &mask, &Input::signal_mask);
//? Start runner thread
Runner::thread_sem_init();
@@ -1029,9 +1038,10 @@ int main(int argc, char **argv) {
{
const auto [x, y] = Term::get_min_size(Config::getS("shown_boxes"));
if (Term::height < y or Term::width < x) {
+ pthread_sigmask(SIG_SETMASK, &Input::signal_mask, &mask);
term_resize(true);
+ pthread_sigmask(SIG_SETMASK, &mask, nullptr);
Global::resized = false;
- Input::interrupt = false;
}
}
diff --git a/src/btop_input.cpp b/src/btop_input.cpp
index fb9e46d..fbbae58 100644
--- a/src/btop_input.cpp
+++ b/src/btop_input.cpp
@@ -16,12 +16,13 @@ indent = tab
tab-size = 4
*/
-#include <iostream>
+#include <limits>
#include <ranges>
#include <vector>
#include <thread>
#include <mutex>
#include <signal.h>
+#include <sys/select.h>
#include <utility>
#include "btop_input.hpp"
@@ -31,17 +32,6 @@ tab-size = 4
#include "btop_menu.hpp"
#include "btop_draw.hpp"
-
-#include "btop_input.hpp"
-#include "btop_tools.hpp"
-#include "btop_config.hpp"
-#include "btop_shared.hpp"
-#include "btop_menu.hpp"
-#include "btop_draw.hpp"
-
-
-using std::cin;
-
using namespace Tools;
using namespace std::literals; // for operator""s
namespace rng = std::ranges;
@@ -89,83 +79,45 @@ namespace Input {
{"[24~", "f12"}
};
- std::atomic<bool> interrupt (false);
+ sigset_t signal_mask;
std::atomic<bool> polling (false);
array<int, 2> mouse_pos;
std::unordered_map<string, Mouse_loc> mouse_mappings;
deque<string> history(50, "");
string old_filter;
+ string input;
- 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<std::mutex> g(lock);
- current.push_back(ch);
- if (current.size() > 100) {
- current.clear();
- }
- }
- }
-
- size_t avail() {
- std::lock_guard<std::mutex> g(lock);
-
- return current.size();
+ bool poll(const uint64_t timeout) {
+ atomic_lock lck(polling);
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds);
+ struct timespec wait;
+ struct timespec *waitptr = nullptr;
+
+ if(timeout != std::numeric_limits<uint64_t>::max()) {
+ wait.tv_sec = timeout / 1000;
+ wait.tv_nsec = (timeout % 1000) * 1000000;
+ waitptr = &wait;
}
- std::string get() {
- std::string res;
-
- {
- std::lock_guard<std::mutex> g(lock);
-
- res.swap(current);
+ if(pselect(STDIN_FILENO + 1, &fds, nullptr, nullptr, waitptr, &signal_mask) > 0) {
+ input.clear();
+ char buf[1024];
+ ssize_t count = 0;
+ while((count = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
+ input.append(std::string_view(buf, count));
}
- return res;
- }
-
- static InputThr& instance() {
- // intentional memory leak, to simplify shutdown process
- static InputThr* input = new InputThr();
-
- return *input;
+ return true;
}
- std::string current;
- // TODO(pg83): use std::conditional_variable instead of sleep
- std::mutex lock;
- std::thread thr;
- };
-
- bool poll(int timeout) {
- atomic_lock lck(polling);
- if (timeout < 1) return InputThr::instance().avail() > 0;
- while (timeout > 0) {
- if (interrupt) {
- interrupt = false;
- return false;
- }
- if (InputThr::instance().avail() > 0) return true;
- sleep_ms(timeout < 10 ? timeout : 10);
- timeout -= 10;
- }
return false;
}
string get() {
- string key = InputThr::instance().get();
+ string key = input;
if (not key.empty()) {
//? Remove escape code prefix if present
if (key.substr(0, 2) == Fx::e) {
@@ -238,12 +190,14 @@ namespace Input {
}
string wait() {
- while (InputThr::instance().avail() < 1) {
- sleep_ms(10);
- }
+ while(not poll(std::numeric_limits<uint64_t>::max())) {}
return get();
}
+ void interrupt() {
+ kill(getpid(), SIGUSR1);
+ }
+
void clear() {
// do not need it, actually
}
diff --git a/src/btop_input.hpp b/src/btop_input.hpp
index fc6fda0..13f14fe 100644
--- a/src/btop_input.hpp
+++ b/src/btop_input.hpp
@@ -29,9 +29,9 @@ using std::atomic;
using std::deque;
using std::string;
-/* The input functions relies on the following std::cin options being set:
- cin.sync_with_stdio(false);
- cin.tie(nullptr);
+/* The input functions rely on the following termios parameters being set:
+ Non-canonical mode (c_lflags & ~(ICANON))
+ VMIN and VTIME (c_cc) set to 0
These will automatically be set when running Term::init() from btop_tools.cpp
*/
@@ -45,7 +45,9 @@ namespace Input {
//? line, col, height, width
extern std::unordered_map<string, Mouse_loc> mouse_mappings;
- extern atomic<bool> interrupt;
+ //* Signal mask used during polling read
+ extern sigset_t signal_mask;
+
extern atomic<bool> polling;
//* Mouse column and line position
@@ -55,7 +57,7 @@ namespace Input {
extern deque<string> history;
//* Poll keyboard & mouse input for <timeout> ms and return input availabilty as a bool
- bool poll(int timeout=0);
+ bool poll(const uint64_t timeout=0);
//* Get a key or mouse action from input
string get();
@@ -63,6 +65,9 @@ namespace Input {
//* Wait until input is available and return key
string wait();
+ //* Interrupt poll/wait
+ void interrupt();
+
//* Clears last entered key
void clear();
diff --git a/src/btop_tools.cpp b/src/btop_tools.cpp
index 967e2f1..47c53bc 100644
--- a/src/btop_tools.cpp
+++ b/src/btop_tools.cpp
@@ -37,7 +37,6 @@ tab-size = 4
#include "btop_tools.hpp"
#include "btop_config.hpp"
-using std::cin;
using std::cout;
using std::floor;
using std::flush;
@@ -77,7 +76,11 @@ namespace Term {
struct termios settings;
if (tcgetattr(STDIN_FILENO, &settings)) return false;
if (on) settings.c_lflag |= ICANON;
- else settings.c_lflag &= ~(ICANON);
+ else {
+ settings.c_lflag &= ~(ICANON);
+ settings.c_cc[VMIN] = 0;
+ settings.c_cc[VTIME] = 0;
+ }
if (tcsetattr(STDIN_FILENO, TCSANOW, &settings)) return false;
if (on) setlinebuf(stdin);
else setbuf(stdin, nullptr);
@@ -152,12 +155,10 @@ namespace Term {
//? Disable stream sync - this does not seem to work on OpenBSD
#ifndef __OpenBSD__
- cin.sync_with_stdio(false);
cout.sync_with_stdio(false);
#endif
//? Disable stream ties
- cin.tie(nullptr);
cout.tie(nullptr);
echo(false);
linebuffered(false);