Merge pull request #1809 from psychon/reap_children

Reap children even across a restart
This commit is contained in:
Emmanuel Lepage Vallée 2017-06-01 22:32:02 -04:00 committed by GitHub
commit 6254e6b7d3
3 changed files with 64 additions and 1 deletions

View File

@ -115,6 +115,8 @@ awesome_atexit(bool restart)
/* Disconnect *after* closing lua */ /* Disconnect *after* closing lua */
xcb_cursor_context_free(globalconf.cursor_ctx); xcb_cursor_context_free(globalconf.cursor_ctx);
xcb_disconnect(globalconf.connection); xcb_disconnect(globalconf.connection);
spawn_before_exit(restart);
} }
/** Restore the client order after a restart */ /** Restore the client order after a restart */

62
spawn.c
View File

@ -62,6 +62,12 @@
/** 20 seconds timeout */ /** 20 seconds timeout */
#define AWESOME_SPAWN_TIMEOUT 20.0 #define AWESOME_SPAWN_TIMEOUT 20.0
static int
compare_pids(const void *a, const void *b)
{
return *(GPid *) a - *(GPid *)b;
}
/** Wrapper for unrefing startup sequence. /** Wrapper for unrefing startup sequence.
*/ */
static inline void static inline void
@ -73,7 +79,11 @@ a_sn_startup_sequence_unref(SnStartupSequence **sss)
DO_ARRAY(SnStartupSequence *, SnStartupSequence, a_sn_startup_sequence_unref) DO_ARRAY(SnStartupSequence *, SnStartupSequence, a_sn_startup_sequence_unref)
/** The array of startup sequence running */ /** The array of startup sequence running */
SnStartupSequence_array_t sn_waits; static SnStartupSequence_array_t sn_waits;
DO_BARRAY(GPid, pid, DO_NOTHING, compare_pids)
static pid_array_t running_children;
/** Remove a SnStartupSequence pointer from an array and forget about it. /** Remove a SnStartupSequence pointer from an array and forget about it.
* \param s The startup sequence to found, remove and unref. * \param s The startup sequence to found, remove and unref.
@ -256,6 +266,20 @@ spawn_start_notify(client_t *c, const char * startup_id)
} }
} }
static void
remove_running_child(GPid pid, gint status, gpointer user_data)
{
(void) status;
(void) user_data;
GPid *pid_in_array = pid_array_lookup(&running_children, &pid);
if (pid_in_array != NULL) {
pid_array_remove(&running_children, pid_in_array);
} else {
warn("(Partially) unknown child %d exited?!", (int) pid);
}
}
/** Initialize program spawner. /** Initialize program spawner.
*/ */
void void
@ -267,6 +291,40 @@ spawn_init(void)
globalconf.default_screen, globalconf.default_screen,
spawn_monitor_event, spawn_monitor_event,
NULL, NULL); NULL, NULL);
const char* children = getenv("AWESOME_RUNNING_CHILDREN");
while (children != NULL) {
int pid, length;
if (sscanf(children, "%d%n", &pid, &length) != 1)
break;
children += length;
if (*children == ',')
children++;
pid_array_insert(&running_children, pid);
g_child_watch_add((GPid) pid, remove_running_child, NULL);
}
unsetenv("AWESOME_RUNNING_CHILDREN");
}
/** Called right before exit, serialise state in case of a restart.
*/
void
spawn_before_exit(bool restart)
{
if (!restart)
return;
buffer_t buffer;
buffer_init(&buffer);
foreach(pid, running_children) {
if(buffer.len != 0)
buffer_addc(&buffer, ',');
buffer_addf(&buffer, "%d", (int) *pid);
}
if(buffer.len != 0)
setenv("AWESOME_RUNNING_CHILDREN", buffer.s, 1);
buffer_wipe(&buffer);
} }
static gboolean static gboolean
@ -345,6 +403,7 @@ child_exit_callback(GPid pid, gint status, gpointer user_data)
{ {
lua_State *L = globalconf_get_lua_State(); lua_State *L = globalconf_get_lua_State();
int exit_callback = GPOINTER_TO_INT(user_data); int exit_callback = GPOINTER_TO_INT(user_data);
remove_running_child(pid, status, user_data);
/* 'Decode' the exit status */ /* 'Decode' the exit status */
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
@ -458,6 +517,7 @@ luaA_spawn(lua_State *L)
int exit_callback = LUA_REFNIL; int exit_callback = LUA_REFNIL;
/* Only do this down here to avoid leaks in case of errors */ /* Only do this down here to avoid leaks in case of errors */
luaA_registerfct(L, 6, &exit_callback); luaA_registerfct(L, 6, &exit_callback);
pid_array_insert(&running_children, pid);
g_child_watch_add(pid, child_exit_callback, GINT_TO_POINTER(exit_callback)); g_child_watch_add(pid, child_exit_callback, GINT_TO_POINTER(exit_callback));
} }

View File

@ -27,6 +27,7 @@
#include <lua.h> #include <lua.h>
void spawn_init(void); void spawn_init(void);
void spawn_before_exit(bool);
void spawn_start_notify(client_t *, const char *); void spawn_start_notify(client_t *, const char *);
int luaA_spawn(lua_State *); int luaA_spawn(lua_State *);