diff options
author | Marvin Borner | 2021-05-22 12:36:08 +0200 |
---|---|---|
committer | Marvin Borner | 2021-05-22 12:36:08 +0200 |
commit | 0bf64a113f3d3baa110b362fd6a215ef29182671 (patch) | |
tree | 5af1c862945741aa2a56b0e72cc25c845eaac12a | |
parent | 93174e167a6aa313fca43f4cb0e9b975e1618468 (diff) |
Enabled window ping-pong checks
-rw-r--r-- | apps/wm/main.c | 122 | ||||
-rw-r--r-- | libs/libgui/gui.c | 23 | ||||
-rw-r--r-- | libs/libgui/msg.c | 8 | ||||
-rw-r--r-- | libs/libgui/msg.h | 5 |
4 files changed, 128 insertions, 30 deletions
diff --git a/apps/wm/main.c b/apps/wm/main.c index 698d0cb..0c30a3f 100644 --- a/apps/wm/main.c +++ b/apps/wm/main.c @@ -36,6 +36,7 @@ struct rectangle { // Global vars ftw! static u8 bypp = 4; static struct fb_generic screen = { 0 }; +static struct list *ping_await = NULL; static struct list *windows = NULL; // THIS LIST SHALL BE SORTED BY Z-INDEX! static struct window *direct = NULL; static struct window *wallpaper = NULL; @@ -360,6 +361,15 @@ static void window_destroy(struct window *win) memset(win->ctx.fb, 0, win->ctx.bytes); rectangle_redraw(win->pos, vec2_add(win->pos, win->ctx.size)); list_remove(windows, list_first_data(windows, win)); + + // Remove window from ping list + struct node *iterator = ping_await->head; + while (iterator) { + if (iterator->data == win) + list_remove(ping_await, iterator); + iterator = iterator->next; + } + sys_free(win->ctx.fb); free(win); } @@ -375,6 +385,71 @@ static void window_request_destroy(struct window *win) } /** + * Window ping-pong + */ + +#define PING_INTERVAL 100 +#define PING_COUNT 3 // -> kill if >= + +static void window_ping(struct window *win) +{ + struct message_ping_window msg = { 0 }; + msg.header.state = MSG_NEED_ANSWER; + msg.ping = MSG_PING_SEND; + msg.id = win->id; + + if (msg_connect_conn(win->client.conn) == EOK) { + list_add(ping_await, win); + msg_send(GUI_PING_WINDOW, &msg, sizeof(msg)); + } +} + +static u32 window_ping_count(struct window *win) +{ + u32 count = 0; + struct node *iterator = ping_await->head; + while (iterator) { + if (iterator->data == win) + count++; + iterator = iterator->next; + } + return count; +} + +static void window_ping_check(void) +{ + struct node *iterator = windows->head; + while (iterator) { + struct window *win = iterator->data; + if (window_ping_count(win) >= PING_COUNT) { + log("Window didn't answer to ping, destroying\n"); + window_destroy(win); + } + iterator = iterator->next; + } +} + +static void window_ping_all(void) +{ + static struct timer last = { 0 }; + struct timer timer; + io_read(IO_TIMER, &timer, 0, sizeof(timer)); + if (timer.time - last.time > PING_INTERVAL) { + window_ping_check(); + + struct node *iterator = windows->head; + while (iterator) { + struct window *win = iterator->data; + if (!(win->flags & WF_NO_WINDOW)) + window_ping(win); + iterator = iterator->next; + } + + last = timer; + } +} + +/** * Window bar */ @@ -570,11 +645,31 @@ static void handle_message_destroy_window(struct message_destroy_window *msg) } } +static void handle_message_ping_window(struct message_ping_window *msg) +{ + if (msg->ping != MSG_PING_RECV || !(msg->header.type & MSG_SUCCESS)) { + log("Invalid ping answer\n"); + return; + } + + struct node *iterator = ping_await->head; + while (iterator) { + struct window *win = iterator->data; + if (win->id == msg->id) { + list_remove(ping_await, iterator); + return; + } + iterator = iterator->next; + } + + log("Unknown ping answer origin\n"); +} + static void handle_message(void *msg) { struct message_header *header = msg; - switch (header->type) { + switch (header->type & ~(MSG_SUCCESS | MSG_FAILURE)) { case GUI_NEW_WINDOW: handle_message_new_window(msg); break; @@ -584,10 +679,13 @@ static void handle_message(void *msg) case GUI_DESTROY_WINDOW: handle_message_destroy_window(msg); break; + case GUI_PING_WINDOW: + handle_message_ping_window(msg); + break; default: log("Message type %d not implemented!\n", header->type); msg_connect_conn(header->bus.conn); - msg_send(GUI_DESTROY_WINDOW | MSG_SUCCESS, msg, sizeof(header)); + msg_send(GUI_DESTROY_WINDOW | MSG_SUCCESS, msg, sizeof(*header)); } } @@ -599,6 +697,9 @@ static void handle_exit(void) if (screen.fb) memset(screen.fb, COLOR_RED, screen.height * screen.pitch); + if (ping_await) + list_destroy(ping_await); + if (windows) { struct node *iterator = windows->head; while (iterator) { @@ -628,6 +729,8 @@ int main(int argc, char **argv) wm_client = (struct client){ .conn = 0 }; bypp = (screen.bpp >> 3); + ping_await = list_new(); + windows = list_new(); keymap = keymap_parse("/res/keymaps/en.keymap"); @@ -659,21 +762,18 @@ int main(int argc, char **argv) if ((poll_ret = io_poll(listeners)) >= 0) { if (poll_ret == IO_KEYBOARD) { if (io_read(IO_KEYBOARD, &event_keyboard, 0, - sizeof(event_keyboard)) > 0) { + sizeof(event_keyboard)) > 0) handle_event_keyboard(&event_keyboard); - continue; - } } else if (poll_ret == IO_MOUSE) { - if (io_read(IO_MOUSE, &event_mouse, 0, sizeof(event_mouse)) > 0) { + if (io_read(IO_MOUSE, &event_mouse, 0, sizeof(event_mouse)) > 0) handle_event_mouse(&event_mouse); - continue; - } } else if (poll_ret == IO_BUS) { - if (msg_receive(msg, sizeof(msg)) > 0) { + if (msg_receive(msg, sizeof(msg)) > 0) handle_message(msg); - continue; - } } + + window_ping_all(); + continue; } panic("Poll/read error: %s\n", strerror(errno)); } diff --git a/libs/libgui/gui.c b/libs/libgui/gui.c index dab00a6..b53c366 100644 --- a/libs/libgui/gui.c +++ b/libs/libgui/gui.c @@ -572,11 +572,9 @@ INLINE void gui_new_window(u32 *id) void gui_redraw_window_only(u32 id) { - struct message_redraw_window msg = { .id = id, .header.state = MSG_NEED_ANSWER }; + struct message_redraw_window msg = { .id = id }; gui_connect_wm(); - if (msg_send(GUI_REDRAW_WINDOW, &msg, sizeof(msg)) > 0 && - msg_receive(&msg, sizeof(msg)) > 0 && - msg.header.type == (GUI_REDRAW_WINDOW | MSG_SUCCESS)) + if (msg_send(GUI_REDRAW_WINDOW, &msg, sizeof(msg)) > 0) return; gui_error(EINVAL); @@ -620,26 +618,25 @@ static void gui_destroy_windows(void) * Message handling */ -static void gui_handle_ping(struct message_ping *msg) +static void gui_handle_ping_window(struct message_ping_window *msg) { if (msg->ping != MSG_PING_SEND) gui_error(EINVAL); - msg->header.type |= MSG_SUCCESS; msg->ping = MSG_PING_RECV; if (msg_connect_conn(msg->header.bus.conn) == EOK && - msg_send(GUI_PING, msg, sizeof(msg)) == EOK) + msg_send(msg->header.type | MSG_SUCCESS, msg, sizeof(*msg)) > 0) return; - gui_error(errno); + gui_error(EINVAL); } static void gui_handle_mouse(struct message_mouse *msg) { if (msg->header.state == MSG_NEED_ANSWER) { if (msg_connect_conn(msg->header.bus.conn) == EOK && - msg_send(msg->header.type | MSG_SUCCESS, msg, sizeof(msg)) == EOK) + msg_send(msg->header.type | MSG_SUCCESS, msg, sizeof(*msg)) > 0) return; - gui_error(errno); + gui_error(EINVAL); } struct gui_widget widget = { 0 }; @@ -698,12 +695,12 @@ void gui_loop(void) while (gui_connect_wm(), msg_receive(msg, 4096) > 0) { struct message_header *head = (void *)msg; switch (head->type) { - case GUI_PING: - gui_handle_ping((void *)msg); - break; case GUI_MOUSE: gui_handle_mouse((void *)msg); break; + case GUI_PING_WINDOW: + gui_handle_ping_window((void *)msg); + break; case GUI_DESTROY_WINDOW: gui_handle_destroy_window((void *)msg); break; diff --git a/libs/libgui/msg.c b/libs/libgui/msg.c index 70a77a1..eda4c34 100644 --- a/libs/libgui/msg.c +++ b/libs/libgui/msg.c @@ -11,14 +11,14 @@ res msg_connect_bus(const char *bus, u32 *conn) { res ret = io_control(IO_BUS, IOCTL_BUS_CONNECT_BUS, bus, conn); - assert(ret == EOK && *conn); - return EOK; + /* assert(ret == EOK && *conn); */ + return ret; } res msg_connect_conn(u32 conn) { res ret = io_control(IO_BUS, IOCTL_BUS_CONNECT_CONN, conn); - assert(ret == EOK); + /* assert(ret == EOK); */ return ret; } @@ -29,7 +29,7 @@ res msg_send(enum message_type type, void *data, u32 size) header->magic = MSG_MAGIC; header->type = type; res ret = io_write(IO_BUS, (u8 *)data + sizeof(struct bus_header), 0, size); - assert(ret >= EOK); + /* assert(ret >= EOK); */ return ret; } diff --git a/libs/libgui/msg.h b/libs/libgui/msg.h index 4bffb74..71491c4 100644 --- a/libs/libgui/msg.h +++ b/libs/libgui/msg.h @@ -26,8 +26,9 @@ struct message_header { enum message_state state; }; -struct message_ping { +struct message_ping_window { struct message_header header; + u32 id; u32 ping; }; @@ -64,7 +65,7 @@ struct message_mouse { }; enum message_type { - GUI_PING, + GUI_PING_WINDOW, GUI_NEW_WINDOW, GUI_REDRAW_WINDOW, GUI_DESTROY_WINDOW, |