aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/main.c
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-25 15:29:36 +0100
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-25 15:57:04 +0100
commite370187394c90e5953eb31f18f574df773fd11eb (patch)
tree6102e1314641dd13518fa35981170b79db90098b /swaybar/main.c
parentMerge pull request #403 from crondog/master (diff)
downloadsway-e370187394c90e5953eb31f18f574df773fd11eb.tar.gz
sway-e370187394c90e5953eb31f18f574df773fd11eb.tar.zst
sway-e370187394c90e5953eb31f18f574df773fd11eb.zip
swaybar: Fix json related crash.
This should fix the random json related crashes in swaybar. The crashes occured because the same socket was used for listening on workspace events and requesting workspace info, resulting in a unreliable message queue on the socket. The solution is to use one socket for the events and one socket for reliably requesting workspace/output info.
Diffstat (limited to 'swaybar/main.c')
-rw-r--r--swaybar/main.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/swaybar/main.c b/swaybar/main.c
index 9f735f36..b6d93f4b 100644
--- a/swaybar/main.c
+++ b/swaybar/main.c
@@ -59,7 +59,7 @@ struct status_block {
59list_t *status_line = NULL; 59list_t *status_line = NULL;
60 60
61list_t *workspaces = NULL; 61list_t *workspaces = NULL;
62int socketfd; 62int ipc_socketfd, ipc_listen_socketfd;
63pid_t pid; 63pid_t pid;
64int status_read_fd; 64int status_read_fd;
65char line[1024]; 65char line[1024];
@@ -142,6 +142,14 @@ void swaybar_teardown() {
142 if (status_read_fd) { 142 if (status_read_fd) {
143 close(status_read_fd); 143 close(status_read_fd);
144 } 144 }
145
146 if (ipc_socketfd) {
147 close(ipc_socketfd);
148 }
149
150 if (ipc_listen_socketfd) {
151 close(ipc_listen_socketfd);
152 }
145} 153}
146 154
147void sway_terminate(void) { 155void sway_terminate(void) {
@@ -181,7 +189,7 @@ void ipc_update_workspaces() {
181 workspaces = create_list(); 189 workspaces = create_list();
182 190
183 uint32_t len = 0; 191 uint32_t len = 0;
184 char *res = ipc_single_command(socketfd, IPC_GET_WORKSPACES, NULL, &len); 192 char *res = ipc_single_command(ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len);
185 json_object *results = json_tokener_parse(res); 193 json_object *results = json_tokener_parse(res);
186 if (!results) { 194 if (!results) {
187 free(res); 195 free(res);
@@ -189,12 +197,12 @@ void ipc_update_workspaces() {
189 } 197 }
190 198
191 int i; 199 int i;
192 for (i = 0; i < json_object_array_length(results); ++i) { 200 int length = json_object_array_length(results);
193 json_object *ws_json = json_object_array_get_idx(results, i); 201 json_object *ws_json;
194 json_object *num, *name, *visible, *focused, *out, *urgent; 202 json_object *num, *name, *visible, *focused, *out, *urgent;
195 if (!ws_json) { 203 for (i = 0; i < length; ++i) {
196 return; 204 ws_json = json_object_array_get_idx(results, i);
197 } 205
198 json_object_object_get_ex(ws_json, "num", &num); 206 json_object_object_get_ex(ws_json, "num", &num);
199 json_object_object_get_ex(ws_json, "name", &name); 207 json_object_object_get_ex(ws_json, "name", &name);
200 json_object_object_get_ex(ws_json, "visible", &visible); 208 json_object_object_get_ex(ws_json, "visible", &visible);
@@ -259,7 +267,7 @@ static const int ws_spacing = 1;
259 267
260void bar_ipc_init(int outputi, const char *bar_id) { 268void bar_ipc_init(int outputi, const char *bar_id) {
261 uint32_t len = 0; 269 uint32_t len = 0;
262 char *res = ipc_single_command(socketfd, IPC_GET_OUTPUTS, NULL, &len); 270 char *res = ipc_single_command(ipc_socketfd, IPC_GET_OUTPUTS, NULL, &len);
263 json_object *outputs = json_tokener_parse(res); 271 json_object *outputs = json_tokener_parse(res);
264 json_object *info = json_object_array_get_idx(outputs, outputi); 272 json_object *info = json_object_array_get_idx(outputs, outputi);
265 json_object *name; 273 json_object *name;
@@ -269,7 +277,7 @@ void bar_ipc_init(int outputi, const char *bar_id) {
269 json_object_put(outputs); 277 json_object_put(outputs);
270 278
271 len = strlen(bar_id); 279 len = strlen(bar_id);
272 res = ipc_single_command(socketfd, IPC_GET_BAR_CONFIG, bar_id, &len); 280 res = ipc_single_command(ipc_socketfd, IPC_GET_BAR_CONFIG, bar_id, &len);
273 281
274 json_object *bar_config = json_tokener_parse(res); 282 json_object *bar_config = json_tokener_parse(res);
275 json_object *tray_output, *mode, *hidden_state, *position, *_status_command; 283 json_object *tray_output, *mode, *hidden_state, *position, *_status_command;
@@ -384,7 +392,7 @@ void bar_ipc_init(int outputi, const char *bar_id) {
384 392
385 const char *subscribe_json = "[ \"workspace\" ]"; 393 const char *subscribe_json = "[ \"workspace\" ]";
386 len = strlen(subscribe_json); 394 len = strlen(subscribe_json);
387 res = ipc_single_command(socketfd, IPC_SUBSCRIBE, subscribe_json, &len); 395 res = ipc_single_command(ipc_listen_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
388 396
389 ipc_update_workspaces(); 397 ipc_update_workspaces();
390} 398}
@@ -822,7 +830,7 @@ void poll_for_update() {
822 830
823 dirty = false; 831 dirty = false;
824 FD_ZERO(&readfds); 832 FD_ZERO(&readfds);
825 FD_SET(socketfd, &readfds); 833 FD_SET(ipc_listen_socketfd, &readfds);
826 FD_SET(status_read_fd, &readfds); 834 FD_SET(status_read_fd, &readfds);
827 835
828 activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); 836 activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
@@ -830,10 +838,10 @@ void poll_for_update() {
830 sway_log(L_ERROR, "polling failed: %d", errno); 838 sway_log(L_ERROR, "polling failed: %d", errno);
831 } 839 }
832 840
833 if (FD_ISSET(socketfd, &readfds)) { 841 if (FD_ISSET(ipc_listen_socketfd, &readfds)) {
834 sway_log(L_DEBUG, "Got workspace update."); 842 sway_log(L_DEBUG, "Got workspace update.");
835 uint32_t len; 843 uint32_t len;
836 char *buf = ipc_recv_response(socketfd, &len); 844 char *buf = ipc_recv_response(ipc_listen_socketfd, &len);
837 free(buf); 845 free(buf);
838 ipc_update_workspaces(); 846 ipc_update_workspaces();
839 dirty = true; 847 dirty = true;
@@ -937,7 +945,9 @@ int main(int argc, char **argv) {
937 sway_abort("Unable to retrieve socket path"); 945 sway_abort("Unable to retrieve socket path");
938 } 946 }
939 } 947 }
940 socketfd = ipc_open_socket(socket_path); 948 ipc_socketfd = ipc_open_socket(socket_path);
949 ipc_listen_socketfd = ipc_open_socket(socket_path);
950
941 951
942 if (argc == optind) { 952 if (argc == optind) {
943 sway_abort("No output index provided"); 953 sway_abort("No output index provided");