aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--TODO7
-rw-r--r--src/spawn.c29
2 files changed, 30 insertions, 6 deletions
diff --git a/TODO b/TODO
index e9bf2ac..f967b1d 100644
--- a/TODO
+++ b/TODO
@@ -16,11 +16,8 @@ Known Bugs:
https://github.com/Bill-Gray/PDCursesMod/issues/322
* Win32: Interrupting <EC> will sometimes hang.
Affects both PDCurses/WinGUI and Gtk.
- In this case you have to kill the subprocess using the task manager.
- Could this be a race condition when adding the process to the job object?
- Perhaps the child process should be created suspended before being added
- to the job object. Glib does not currently allow that.
- This could already be fixed.
+ This no longer happens with ECbash -c 'while true; do true; done'$.
+ However ECping -t 8.8.8.8$ still cannot be interrupted.
* dlmalloc's malloc_trim() does not seem to free any resident memory
after hitting the OOM limit, eg. after <%a>.
Apparently an effect of HAVE_MORECORE (sbrk()) - some allocation is
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);