Fix multi-client server suspend

This commit is contained in:
Maxime Coste 2019-09-09 20:11:04 +10:00
parent f43ac3d78b
commit 006083c6f8
3 changed files with 37 additions and 42 deletions

View File

@ -477,7 +477,6 @@ void register_options()
static Client* local_client = nullptr;
static int local_client_exit = 0;
static UserInterface* local_ui = nullptr;
static bool convert_to_client_pending = false;
enum class UIType
@ -550,26 +549,10 @@ std::unique_ptr<UserInterface> create_local_ui(UIType ui_type)
{
LocalUI()
{
kak_assert(not local_ui);
local_ui = this;
m_old_sigtstp = set_signal_handler(SIGTSTP, [](int) {
set_signal_handler(SIGTSTP, [](int) {
if (ClientManager::instance().count() == 1 and
*ClientManager::instance().begin() == local_client)
{
// Suspend normally if we are the only client
auto current = set_signal_handler(SIGTSTP, static_cast<LocalUI*>(local_ui)->m_old_sigtstp);
sigset_t unblock_sigtstp, old_mask;
sigemptyset(&unblock_sigtstp);
sigaddset(&unblock_sigtstp, SIGTSTP);
sigprocmask(SIG_UNBLOCK, &unblock_sigtstp, &old_mask);
raise(SIGTSTP);
set_signal_handler(SIGTSTP, current);
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
}
NCursesUI::instance().suspend();
else
convert_to_client_pending = true;
});
@ -577,23 +560,17 @@ std::unique_ptr<UserInterface> create_local_ui(UIType ui_type)
~LocalUI() override
{
set_signal_handler(SIGTSTP, m_old_sigtstp);
local_client = nullptr;
local_ui = nullptr;
if (not convert_to_client_pending and
not ClientManager::instance().empty())
{
if (convert_to_client_pending or
ClientManager::instance().empty())
return;
if (fork_server_to_background())
{
this->NCursesUI::~NCursesUI();
exit(local_client_exit);
}
}
}
private:
using SigHandler = void (*)(int);
SigHandler m_old_sigtstp;
};
if (not isatty(1))

View File

@ -373,6 +373,7 @@ NCursesUI::NCursesUI()
set_signal_handler(SIGWINCH, &signal_handler<&resize_pending>);
set_signal_handler(SIGHUP, &signal_handler<&sighup_raised>);
set_signal_handler(SIGTSTP, [](int){ NCursesUI::instance().suspend(); });
check_resize(true);
redraw(false);
@ -390,6 +391,29 @@ NCursesUI::~NCursesUI()
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
set_signal_handler(SIGWINCH, SIG_DFL);
set_signal_handler(SIGCONT, SIG_DFL);
set_signal_handler(SIGTSTP, SIG_DFL);
}
void NCursesUI::suspend()
{
bool mouse_enabled = m_mouse_enabled;
enable_mouse(false);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
auto current = set_signal_handler(SIGTSTP, SIG_DFL);
sigset_t unblock_sigtstp, old_mask;
sigemptyset(&unblock_sigtstp);
sigaddset(&unblock_sigtstp, SIGTSTP);
sigprocmask(SIG_UNBLOCK, &unblock_sigtstp, &old_mask);
raise(SIGTSTP); // suspend here
set_signal_handler(SIGTSTP, current);
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
check_resize(true);
set_raw_mode();
enable_mouse(mouse_enabled);
}
void NCursesUI::set_raw_mode() const
@ -612,15 +636,7 @@ Optional<Key> NCursesUI::get_next_key()
return {Key::Backspace};
if (c == control('z'))
{
bool mouse_enabled = m_mouse_enabled;
enable_mouse(false);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
kill(0, SIGTSTP); // We suspend at this line
check_resize(true);
set_raw_mode();
enable_mouse(mouse_enabled);
return {};
}
if (c < 27)

View File

@ -17,7 +17,7 @@ namespace Kakoune
struct NCursesWin;
class NCursesUI : public UserInterface
class NCursesUI : public UserInterface, public Singleton<NCursesUI>
{
public:
NCursesUI();
@ -57,6 +57,8 @@ public:
static void abort();
void suspend();
struct Rect
{
DisplayCoord pos;
@ -117,7 +119,7 @@ private:
Window m_window;
DisplayCoord m_dimensions;
termios m_original_termios;
termios m_original_termios{};
void set_raw_mode() const;