kernel: msg: implement asynchronous event messages

This commit is contained in:
2026-03-24 18:32:33 +00:00
parent 110f625f04
commit 89d02c72ee
7 changed files with 178 additions and 56 deletions

View File

@@ -1,16 +1,29 @@
#include <kernel/channel.h>
#include <kernel/port.h>
#include <kernel/printk.h>
#include <kernel/thread.h>
#include <kernel/util.h>
#define PORT_CAST(p) OBJECT_C_CAST(struct port, p_base, &port_type, p)
static kern_status_t port_cleanup(struct object *obj);
static struct object_type port_type = {
.ob_name = "port",
.ob_size = sizeof(struct port),
.ob_header_offset = offsetof(struct port, p_base),
.ob_ops = {
.destroy = port_cleanup,
},
};
static kern_status_t port_cleanup(struct object *obj, struct queue *q)
{
struct port *port = PORT_CAST(obj);
port_disconnect(port);
return KERN_OK;
}
kern_status_t port_type_init(void)
{
return object_type_register(&port_type);
@@ -58,9 +71,26 @@ struct port *port_create(void)
kern_status_t port_connect(struct port *port, struct channel *remote)
{
if (port->p_status != PORT_OFFLINE) {
tracek("port_connect: port in bad state (%d)", port->p_status);
return KERN_BAD_STATE;
}
struct msg *msg = msg_alloc();
if (!msg) {
return KERN_NO_MEMORY;
}
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;
unsigned long flags;
channel_lock_irqsave(remote, &flags);
channel_enqueue_msg(remote, msg);
channel_unlock_irqrestore(remote, flags);
port->p_remote = remote;
port->p_status = PORT_READY;
return KERN_OK;
@@ -69,9 +99,27 @@ kern_status_t port_connect(struct port *port, struct channel *remote)
kern_status_t port_disconnect(struct port *port)
{
if (port->p_status != PORT_READY) {
tracek("port_disconnect: port in bad state (%d)",
port->p_status);
return KERN_BAD_STATE;
}
struct msg *msg = msg_alloc();
if (!msg) {
return KERN_NO_MEMORY;
}
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;
unsigned long flags;
channel_lock_irqsave(port->p_remote, &flags);
channel_enqueue_msg(port->p_remote, msg);
channel_unlock_irqrestore(port->p_remote, flags);
port->p_remote = NULL;
port->p_status = PORT_OFFLINE;
return KERN_OK;
@@ -84,12 +132,14 @@ kern_status_t port_send_msg(
unsigned long *lock_flags)
{
if (port->p_status != PORT_READY) {
tracek("port_send_msg: port in bad state (%d)", port->p_status);
return KERN_BAD_STATE;
}
struct thread *self = current_thread();
struct msg msg;
memset(&msg, 0x0, sizeof msg);
msg.msg_type = KERN_MSG_TYPE_DATA;
msg.msg_status = KMSG_WAIT_RECEIVE;
msg.msg_sender_thread = self;
msg.msg_sender_port = port;