diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-05-09 19:08:32 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-05-09 19:08:32 +0200 |
commit | f557af9a9112955d3b65f6ad0d54c0791189f961 (patch) | |
tree | 9d7718cb1571b624710a182f09aca7163dc673a0 /src/main.c | |
parent | bac1efa51bf889d494013925586e87ef08307529 (diff) | |
download | sciteco-f557af9a9112955d3b65f6ad0d54c0791189f961.tar.gz |
fixed CTRL+C interruptions on Windows; optimized CTRL+C polling on Gtk+
* teco_interrupt() turned out to be unsuitable to kill child processes (eg. when <EB> hangs).
Instead, we have Win32-specific code now.
* Since SIGINT can be ignored on UNIX, pressing CTRL+C was not guaranteed to kill the
child process (eg. when <EB> hangs).
At the same time, it makes sense to send SIGINT first, so programs can terminate gracefully.
The behaviour has therefore been adapted: Interrupting with CTRL+C the first time will kill
gracefully. The second time, a more agressive signal is sent to kill the child process.
Unfortunately, this would be relatively tricky and complicated to do on Windows, so CTRL+C will always
"hard-kill" the child process.
* Moreover, teco_interrupt() killed the entire process on Windows when called the second time.
This resulted in any interruption to terminate SciTECO unexpectedly when tried the second time on Gtk/Win32.
* teco_sigint_occurred renamed to teco_interrupted:
There may be several different sources for setting this flag.
* Checking for CTRL+C on Gtk involves driving the main event loop repeatedly.
This is a very expensive operation. We now do that only every 100ms. This is still sufficient since
keyboard input comes from humans.
This optimization saves 75% runtime on Windows and 90% on Linux.
* The same optimization turned out to be contraproductive on PDCurses/WinGUI.
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 35 |
1 files changed, 8 insertions, 27 deletions
@@ -52,32 +52,13 @@ teco_int_t teco_ed = TECO_ED_AUTOEOL; -volatile sig_atomic_t teco_sigint_occurred = FALSE; - -#ifdef G_OS_UNIX - -void -teco_interrupt(void) -{ - /* - * This sends SIGINT to the entire process group, - * which makes sure that subprocesses are signalled, - * even when called from the wrong thread. - */ - if (kill(0, SIGINT)) - teco_sigint_occurred = TRUE; -} - -#else /* !G_OS_UNIX */ - -void -teco_interrupt(void) -{ - if (raise(SIGINT)) - teco_sigint_occurred = TRUE; -} - -#endif +/** + * Whether there was an asyncronous interruption (usually after pressing CTRL+C). + * However you should always use teco_interface_is_interrupted(), + * to check for interruptions because of its side effects. + * This variable is safe to set to TRUE from signal handlers and threads. + */ +volatile sig_atomic_t teco_interrupted = FALSE; /* * FIXME: Move this into file-utils.c? @@ -309,7 +290,7 @@ teco_initialize_environment(const gchar *program) static void teco_sigint_handler(int signal) { - teco_sigint_occurred = TRUE; + teco_interrupted = TRUE; } int |