diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-10-08 19:28:53 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-10-08 19:28:53 +1000 |
commit | 82423991a8512ab97fbc41d1e190e709c58bc346 (patch) | |
tree | 837e45f94240e02e2ab0f8f931227943e00819b3 /sway/commands/reload.c | |
parent | Merge pull request #2786 from swaywm/no-op-client-commands (diff) | |
download | sway-82423991a8512ab97fbc41d1e190e709c58bc346.tar.gz sway-82423991a8512ab97fbc41d1e190e709c58bc346.tar.zst sway-82423991a8512ab97fbc41d1e190e709c58bc346.zip |
Reload config using idle event
This patch makes it so when you run reload, the actual reloading is
deferred to the next time the event loop becomes idle. This avoids
several use-after-frees and removes the workarounds we have to avoid
them.
When you run reload, we validate the config before creating the idle
event. This is so the reload command will still return an error if there
are validation errors. To allow this, load_main_config has been adjusted
so it doesn't apply the config if validating is true rather than
applying it unconditionally.
This also fixes a memory leak in the reload command where if the config
failed to load, the bar_ids list would not be freed.
Diffstat (limited to 'sway/commands/reload.c')
-rw-r--r-- | sway/commands/reload.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 36fb9092..9e136d48 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c | |||
@@ -3,15 +3,12 @@ | |||
3 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 4 | #include "sway/config.h" |
5 | #include "sway/ipc-server.h" | 5 | #include "sway/ipc-server.h" |
6 | #include "sway/server.h" | ||
6 | #include "sway/tree/arrange.h" | 7 | #include "sway/tree/arrange.h" |
7 | #include "list.h" | 8 | #include "list.h" |
9 | #include "log.h" | ||
8 | 10 | ||
9 | struct cmd_results *cmd_reload(int argc, char **argv) { | 11 | static void do_reload(void *data) { |
10 | struct cmd_results *error = NULL; | ||
11 | if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { | ||
12 | return error; | ||
13 | } | ||
14 | |||
15 | // store bar ids to check against new bars for barconfig_update events | 12 | // store bar ids to check against new bars for barconfig_update events |
16 | list_t *bar_ids = create_list(); | 13 | list_t *bar_ids = create_list(); |
17 | for (int i = 0; i < config->bars->length; ++i) { | 14 | for (int i = 0; i < config->bars->length; ++i) { |
@@ -20,9 +17,12 @@ struct cmd_results *cmd_reload(int argc, char **argv) { | |||
20 | } | 17 | } |
21 | 18 | ||
22 | if (!load_main_config(config->current_config_path, true, false)) { | 19 | if (!load_main_config(config->current_config_path, true, false)) { |
23 | return cmd_results_new(CMD_FAILURE, "reload", | 20 | wlr_log(WLR_ERROR, "Error(s) reloading config"); |
24 | "Error(s) reloading config."); | 21 | list_foreach(bar_ids, free); |
22 | list_free(bar_ids); | ||
23 | return; | ||
25 | } | 24 | } |
25 | |||
26 | ipc_event_workspace(NULL, NULL, "reload"); | 26 | ipc_event_workspace(NULL, NULL, "reload"); |
27 | 27 | ||
28 | load_swaybars(); | 28 | load_swaybars(); |
@@ -37,12 +37,26 @@ struct cmd_results *cmd_reload(int argc, char **argv) { | |||
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | for (int i = 0; i < bar_ids->length; ++i) { | 40 | list_foreach(bar_ids, free); |
41 | free(bar_ids->items[i]); | ||
42 | } | ||
43 | list_free(bar_ids); | 41 | list_free(bar_ids); |
44 | 42 | ||
45 | arrange_root(); | 43 | arrange_root(); |
44 | } | ||
45 | |||
46 | struct cmd_results *cmd_reload(int argc, char **argv) { | ||
47 | struct cmd_results *error = NULL; | ||
48 | if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { | ||
49 | return error; | ||
50 | } | ||
51 | |||
52 | if (!load_main_config(config->current_config_path, true, true)) { | ||
53 | return cmd_results_new(CMD_FAILURE, "reload", | ||
54 | "Error(s) reloading config."); | ||
55 | } | ||
56 | |||
57 | // The reload command frees a lot of stuff, so to avoid use-after-frees | ||
58 | // we schedule the reload to happen using an idle event. | ||
59 | wl_event_loop_add_idle(server.wl_event_loop, do_reload, NULL); | ||
46 | 60 | ||
47 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 61 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
48 | } | 62 | } |