From 95d33ddcb9ed7183367b11df69503e9f07c71322 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 25 Mar 2026 20:19:19 +0000 Subject: [PATCH] kernel: msg: async messages no longer hold a pointer to the thread/port that sent them this prevents a race condition where an event is sent as a port is being destroyed. when the server gets around to handling the event, it now refers to a different port that was created in the mean-time. --- include/kernel/msg.h | 16 ++++++++++++++-- kernel/channel.c | 7 ++++--- kernel/port.c | 8 ++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/include/kernel/msg.h b/include/kernel/msg.h index 414ee87..1f660b8 100644 --- a/include/kernel/msg.h +++ b/include/kernel/msg.h @@ -21,8 +21,20 @@ struct msg { enum kmsg_status msg_status; struct btree_node msg_node; msgid_t msg_id; - struct port *msg_sender_port; - struct thread *msg_sender_thread; + union { + /* only valid for asynchronous messages (msg_status == + * KMSG_ASYNC) */ + struct { + koid_t msg_sender_port_id; + tid_t msg_sender_thread_id; + }; + /* only valid for synchronous messages (msg_status != + * KMSG_ASYNC) */ + struct { + struct port *msg_sender_port; + struct thread *msg_sender_thread; + }; + }; kern_status_t msg_result; kern_msg_type_t msg_type; diff --git a/kernel/channel.c b/kernel/channel.c index 1d40d00..4085872 100644 --- a/kernel/channel.c +++ b/kernel/channel.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -157,12 +158,12 @@ extern kern_status_t channel_recv_msg( /* msg is now set to the next message to process */ if (msg->msg_type != KERN_MSG_TYPE_DATA) { - /* event messages as asynchronous */ + /* event messages are asynchronous */ out_msg->msg_id = msg->msg_id; out_msg->msg_type = msg->msg_type; out_msg->msg_event = msg->msg_event; - out_msg->msg_sender = msg->msg_sender_thread->tr_parent->t_id; - out_msg->msg_endpoint = msg->msg_sender_port->p_base.ob_id; + out_msg->msg_sender = msg->msg_sender_thread_id; + out_msg->msg_endpoint = msg->msg_sender_port_id; spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags); msg_free(msg); diff --git a/kernel/port.c b/kernel/port.c index 3071d83..bcda2b8 100644 --- a/kernel/port.c +++ b/kernel/port.c @@ -83,8 +83,8 @@ kern_status_t port_connect(struct port *port, struct channel *remote) msg->msg_status = KMSG_ASYNC; msg->msg_type = KERN_MSG_TYPE_EVENT; msg->msg_event = KERN_MSG_EVENT_CONNECTION; - msg->msg_sender_thread = current_thread(); - msg->msg_sender_port = port; + msg->msg_sender_thread_id = current_thread()->tr_id; + msg->msg_sender_port_id = port->p_base.ob_id; unsigned long flags; channel_lock_irqsave(remote, &flags); @@ -112,8 +112,8 @@ kern_status_t port_disconnect(struct port *port) msg->msg_status = KMSG_ASYNC; msg->msg_type = KERN_MSG_TYPE_EVENT; msg->msg_event = KERN_MSG_EVENT_DISCONNECTION; - msg->msg_sender_thread = current_thread(); - msg->msg_sender_port = port; + msg->msg_sender_thread_id = current_thread()->tr_id; + msg->msg_sender_port_id = port->p_base.ob_id; unsigned long flags; channel_lock_irqsave(port->p_remote, &flags);