Attempt to exit cleanly, without crash (#51)

This commit is contained in:
tiosgz 2021-12-04 17:25:31 +00:00 committed by GitHub
parent ed1ff87494
commit 53684f0e79
13 changed files with 71 additions and 26 deletions

View file

@ -43,6 +43,7 @@ struct kiwmi_cursor {
struct {
struct wl_signal button_down;
struct wl_signal button_up;
struct wl_signal destroy;
struct wl_signal motion;
struct wl_signal scroll;
} events;

View file

@ -40,5 +40,6 @@ struct kiwmi_keyboard_key_event {
struct kiwmi_keyboard *
keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device);
void keyboard_destroy(struct kiwmi_keyboard *keyboard);
#endif /* KIWMI_INPUT_KEYBOARD_H */

View file

@ -22,6 +22,10 @@ struct kiwmi_server {
struct kiwmi_lua *lua;
struct kiwmi_desktop desktop;
struct kiwmi_input input;
struct {
struct wl_signal destroy;
} events;
};
bool server_init(struct kiwmi_server *server, char *config_path);

View file

@ -85,6 +85,7 @@ void
desktop_fini(struct kiwmi_desktop *desktop)
{
wlr_output_layout_destroy(desktop->output_layout);
desktop->output_layout = NULL;
}
struct kiwmi_output *

View file

@ -264,14 +264,20 @@ output_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
{
struct kiwmi_output *output = wl_container_of(listener, output, destroy);
if (output->desktop->output_layout) {
wlr_output_layout_remove(
output->desktop->output_layout, output->wlr_output);
}
wl_signal_emit(&output->events.destroy, output);
wl_list_remove(&output->link);
wl_list_remove(&output->frame.link);
wl_list_remove(&output->commit.link);
wl_list_remove(&output->destroy.link);
wl_list_remove(&output->mode.link);
wl_list_remove(&output->events.destroy.listener_list);
free(output);
}

View file

@ -239,6 +239,10 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
view_child_destroy(child);
}
if (view->decoration) {
view->decoration->view = NULL;
}
wl_list_remove(&view->link);
wl_list_remove(&view->children);
wl_list_remove(&view->map.link);
@ -250,6 +254,8 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
wl_list_remove(&view->request_move.link);
wl_list_remove(&view->request_resize.link);
wl_list_remove(&view->events.unmap.listener_list);
free(view);
}
@ -509,7 +515,9 @@ xdg_decoration_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
struct kiwmi_xdg_decoration *decoration =
wl_container_of(listener, decoration, destroy);
if (decoration->view) {
decoration->view->decoration = NULL;
}
wl_list_remove(&decoration->destroy.link);
wl_list_remove(&decoration->request_mode.link);

View file

@ -254,6 +254,7 @@ cursor_create(
wl_signal_init(&cursor->events.button_down);
wl_signal_init(&cursor->events.button_up);
wl_signal_init(&cursor->events.destroy);
wl_signal_init(&cursor->events.motion);
wl_signal_init(&cursor->events.scroll);
@ -263,14 +264,12 @@ cursor_create(
void
cursor_destroy(struct kiwmi_cursor *cursor)
{
wl_signal_emit(&cursor->events.destroy, cursor);
wlr_cursor_destroy(cursor->cursor);
wlr_xcursor_manager_destroy(cursor->xcursor_manager);
wl_list_remove(&cursor->cursor_motion.link);
wl_list_remove(&cursor->cursor_motion_absolute.link);
wl_list_remove(&cursor->cursor_button.link);
wl_list_remove(&cursor->cursor_axis.link);
wl_list_remove(&cursor->cursor_frame.link);
// The wlr_cursor is already destroyed, don't unregister listeners
free(cursor);
}

View file

@ -101,7 +101,7 @@ input_fini(struct kiwmi_input *input)
struct kiwmi_keyboard *keyboard;
struct kiwmi_keyboard *tmp;
wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) {
free(keyboard);
keyboard_destroy(keyboard);
}
seat_destroy(input->seat);

View file

@ -116,14 +116,7 @@ keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
struct kiwmi_keyboard *keyboard =
wl_container_of(listener, keyboard, device_destroy);
wl_list_remove(&keyboard->link);
wl_list_remove(&keyboard->modifiers.link);
wl_list_remove(&keyboard->key.link);
wl_list_remove(&keyboard->device_destroy.link);
wl_signal_emit(&keyboard->events.destroy, keyboard);
free(keyboard);
keyboard_destroy(keyboard);
}
struct kiwmi_keyboard *
@ -167,3 +160,19 @@ keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device)
return keyboard;
}
void
keyboard_destroy(struct kiwmi_keyboard *keyboard)
{
wl_list_remove(&keyboard->modifiers.link);
wl_list_remove(&keyboard->key.link);
wl_list_remove(&keyboard->device_destroy.link);
wl_signal_emit(&keyboard->events.destroy, keyboard);
wl_list_remove(&keyboard->link);
wl_list_remove(&keyboard->events.destroy.listener_list);
free(keyboard);
}

View file

@ -309,7 +309,8 @@ luaK_kiwmi_cursor_new(lua_State *L)
struct kiwmi_lua *lua = lua_touserdata(L, 1);
struct kiwmi_cursor *cursor = lua_touserdata(L, 2);
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, cursor, NULL);
struct kiwmi_object *obj =
luaK_get_kiwmi_object(lua, cursor, &cursor->events.destroy);
struct kiwmi_object **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud));
luaL_getmetatable(L, "kiwmi_cursor");

View file

@ -574,7 +574,8 @@ luaK_kiwmi_server_new(lua_State *L)
struct kiwmi_lua *lua = lua_touserdata(L, 1);
struct kiwmi_server *server = lua_touserdata(L, 2);
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, server, NULL);
struct kiwmi_object *obj =
luaK_get_kiwmi_object(lua, server, &server->events.destroy);
struct kiwmi_object **server_ud = lua_newuserdata(L, sizeof(*server_ud));
luaL_getmetatable(L, "kiwmi_server");

View file

@ -39,6 +39,15 @@ luaK_toudata(lua_State *L, int ud, const char *tname)
return NULL;
}
static void
kiwmi_object_destroy(struct kiwmi_object *obj)
{
wl_list_remove(&obj->destroy.link);
wl_list_remove(&obj->events.destroy.listener_list);
free(obj);
}
int
luaK_kiwmi_object_gc(lua_State *L)
{
@ -47,7 +56,7 @@ luaK_kiwmi_object_gc(lua_State *L)
--obj->refcount;
if (obj->refcount == 0 && wl_list_empty(&obj->callbacks)) {
free(obj);
kiwmi_object_destroy(obj);
}
return 0;
@ -71,8 +80,6 @@ kiwmi_object_destroy_notify(struct wl_listener *listener, void *data)
free(lc);
}
wl_list_remove(&obj->destroy.link);
lua_State *L = obj->lua->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, obj->lua->objects);
@ -84,7 +91,7 @@ kiwmi_object_destroy_notify(struct wl_listener *listener, void *data)
obj->valid = false;
if (obj->refcount == 0) {
free(obj);
kiwmi_object_destroy(obj);
}
}
@ -123,9 +130,11 @@ luaK_get_kiwmi_object(
if (destroy) {
obj->destroy.notify = kiwmi_object_destroy_notify;
wl_signal_add(destroy, &obj->destroy);
} else {
wl_list_init(&obj->destroy.link);
}
wl_signal_init(&obj->events.destroy);
}
wl_list_init(&obj->callbacks);

View file

@ -46,6 +46,8 @@ server_init(struct kiwmi_server *server, char *config_path)
struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend);
wlr_renderer_init_wl_display(renderer, server->wl_display);
wl_signal_init(&server->events.destroy);
if (!desktop_init(&server->desktop, renderer)) {
wlr_log(WLR_ERROR, "Failed to initialize desktop");
wl_display_destroy(server->wl_display);
@ -132,12 +134,15 @@ server_fini(struct kiwmi_server *server)
{
wlr_log(WLR_DEBUG, "Shutting down Wayland server");
wl_signal_emit(&server->events.destroy, server);
wl_display_destroy_clients(server->wl_display);
wl_display_destroy(server->wl_display);
desktop_fini(&server->desktop);
input_fini(&server->input);
wl_display_destroy(server->wl_display);
luaK_destroy(server->lua);
free(server->config_path);