aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-05-22 12:36:08 +0200
committerMarvin Borner2021-05-22 12:36:08 +0200
commit0bf64a113f3d3baa110b362fd6a215ef29182671 (patch)
tree5af1c862945741aa2a56b0e72cc25c845eaac12a
parent93174e167a6aa313fca43f4cb0e9b975e1618468 (diff)
Enabled window ping-pong checks
-rw-r--r--apps/wm/main.c122
-rw-r--r--libs/libgui/gui.c23
-rw-r--r--libs/libgui/msg.c8
-rw-r--r--libs/libgui/msg.h5
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,