diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-10-21 22:29:33 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-10-21 22:29:33 +0200 |
commit | e69e7c95bc68a90eadfbd963359737dce43d65f2 (patch) | |
tree | bd2e16484438f4f79ac33dfaf29ed193c76257b5 /src | |
parent | a29382ea5d52f3bf3668b13dfe9a5d39c4769031 (diff) | |
download | sciteco-e69e7c95bc68a90eadfbd963359737dce43d65f2.tar.gz |
fixed some interruptions of <EC> on Win32
* We now recreate the event loop with every call since
it turned out that the idle watcher wouldn't be invoked
after the event loop has been quit once.
This at least fixes interruption of ECbash -c 'while true; do true; done'$.
* Unfortunately, ECping -t 8.8.8.8$ still cannot be interrupted
(unless you manually kill the process from the task manager).
Diffstat (limited to 'src')
-rw-r--r-- | src/spawn.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/spawn.c b/src/spawn.c index a1da5ff..99eb6e3 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -92,10 +92,12 @@ static void __attribute__((constructor)) teco_spawn_init(void) { memset(&teco_spawn_ctx, 0, sizeof(teco_spawn_ctx)); + /* FIXME: Cannot share these objects between calls */ +#if 0 /* * Context and loop can be reused between EC invocations. * However we should not use the default context, since it - * may be used by GTK + * may be used by GTK. */ teco_spawn_ctx.mainctx = g_main_context_new(); teco_spawn_ctx.mainloop = g_main_loop_new(teco_spawn_ctx.mainctx, FALSE); @@ -108,6 +110,7 @@ teco_spawn_init(void) g_source_set_callback(teco_spawn_ctx.idle_src, (GSourceFunc)teco_spawn_idle_cb, NULL, NULL); g_source_attach(teco_spawn_ctx.idle_src, teco_spawn_ctx.mainctx); +#endif } static gchar ** @@ -286,6 +289,20 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr &stdin_fd, &stdout_fd, NULL, error)) goto gerror; + /* + * FIXME: At least on Win32, we cannot resume a main loop + * after it has been quit once, which is obviously a bug. + * Therefore, we cannot cache the context, loop and idle_src. + */ + teco_spawn_ctx.mainctx = g_main_context_new(); + teco_spawn_ctx.mainloop = g_main_loop_new(teco_spawn_ctx.mainctx, FALSE); + + teco_spawn_ctx.idle_src = g_idle_source_new(); + g_source_set_priority(teco_spawn_ctx.idle_src, G_PRIORITY_LOW); + g_source_set_callback(teco_spawn_ctx.idle_src, (GSourceFunc)teco_spawn_idle_cb, + NULL, NULL); + g_source_attach(teco_spawn_ctx.idle_src, teco_spawn_ctx.mainctx); + teco_spawn_ctx.child_src = g_child_watch_source_new(pid); g_source_set_callback(teco_spawn_ctx.child_src, (GSourceFunc)teco_spawn_child_watch_cb, NULL, NULL); @@ -293,6 +310,9 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr teco_spawn_ctx.interrupted = FALSE; #ifdef G_OS_WIN32 + /* + * FIXME: In case of errors, we will leak memory. + */ teco_spawn_ctx.pid = CreateJobObject(NULL, NULL); if (!teco_spawn_ctx.pid) { teco_error_win32_set(error, "Cannot create job object", GetLastError()); @@ -406,6 +426,10 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr CloseHandle(teco_spawn_ctx.pid); #endif + g_source_unref(teco_spawn_ctx.idle_src); + g_main_loop_unref(teco_spawn_ctx.mainloop); + g_main_context_unref(teco_spawn_ctx.mainctx); + /* * NOTE: This includes interruptions following CTRL+C. * But they are reported as G_SPAWN_ERROR_FAILED and hard to filter out. @@ -828,10 +852,13 @@ teco_spawn_idle_cb(gpointer user_data) static void TECO_DEBUG_CLEANUP teco_spawn_cleanup(void) { + /* FIXME: Cannot share these objects between calls */ +#if 0 g_source_unref(teco_spawn_ctx.idle_src); g_main_loop_unref(teco_spawn_ctx.mainloop); g_main_context_unref(teco_spawn_ctx.mainctx); +#endif if (teco_spawn_ctx.error) g_error_free(teco_spawn_ctx.error); |