[kernel] Simplify mailbox interface to call/respond
The only real usage of mailbox was mailbox_call or mailbox_respond_receive. This change simplifies the interface to just these syscalls.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Mailboxes are objects that enable synchronous or asynchronous
|
# Mailboxes are objects that enable synchronous IPC via short message-passing
|
||||||
# IPC via short message-passing of bytes and handles.
|
# of tagged handles.
|
||||||
|
|
||||||
object mailbox : object {
|
object mailbox : object {
|
||||||
uid 99934ad04ece1e07
|
uid 99934ad04ece1e07
|
||||||
@@ -13,23 +13,6 @@ object mailbox : object {
|
|||||||
method create [constructor]
|
method create [constructor]
|
||||||
method close [destructor cap:close]
|
method close [destructor cap:close]
|
||||||
|
|
||||||
# Asynchronously send a message to the reciever
|
|
||||||
method send [cap:send] {
|
|
||||||
param tag uint64
|
|
||||||
param subtag uint64
|
|
||||||
param handles ref object [list]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Receive a pending message, or block waiting for a message to
|
|
||||||
# arrive if block is true.
|
|
||||||
method receive [cap:receive] {
|
|
||||||
param tag uint64 [out]
|
|
||||||
param subtag uint64 [out]
|
|
||||||
param handles ref object [out list zero_ok]
|
|
||||||
param reply_tag uint16 [out optional]
|
|
||||||
param flags uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
# Send a message to the reciever, and block until a
|
# Send a message to the reciever, and block until a
|
||||||
# response is sent. Note that getting this response
|
# response is sent. Note that getting this response
|
||||||
# does not require the receive capability.
|
# does not require the receive capability.
|
||||||
@@ -39,19 +22,11 @@ object mailbox : object {
|
|||||||
param handles ref object [inout list zero_ok]
|
param handles ref object [inout list zero_ok]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Respond to a message sent using call. Note that this
|
|
||||||
# requires the receive capability and not the send capability.
|
|
||||||
method respond [cap:receive] {
|
|
||||||
param tag uint64
|
|
||||||
param subtag uint64
|
|
||||||
param handles ref object [list zero_ok]
|
|
||||||
param reply_tag uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
# Respond to a message sent using call, and wait for another
|
# Respond to a message sent using call, and wait for another
|
||||||
# message to arrive. Note that this does not require the send
|
# message to arrive. Note that this does not require the send
|
||||||
# capability.
|
# capability. A reply tag of 0 skips the reply and goes directly
|
||||||
method respond_receive [cap:receive] {
|
# to waiting for a new message.
|
||||||
|
method respond [cap:receive] {
|
||||||
param tag uint64 [inout]
|
param tag uint64 [inout]
|
||||||
param subtag uint64 [inout]
|
param subtag uint64 [inout]
|
||||||
param handles ref object [inout list zero_ok]
|
param handles ref object [inout list zero_ok]
|
||||||
|
|||||||
@@ -45,18 +45,6 @@ mailbox::close()
|
|||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
mailbox::send(message *msg)
|
|
||||||
{
|
|
||||||
util::scoped_lock lock {m_message_lock};
|
|
||||||
m_messages.push_back(msg);
|
|
||||||
|
|
||||||
thread *t = m_queue.pop_next();
|
|
||||||
|
|
||||||
lock.release();
|
|
||||||
if (t) t->wake(has_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
mailbox::call(message *msg)
|
mailbox::call(message *msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,11 +39,6 @@ public:
|
|||||||
/// Check if the mailbox has been closed
|
/// Check if the mailbox has been closed
|
||||||
inline bool closed() const { return m_closed; }
|
inline bool closed() const { return m_closed; }
|
||||||
|
|
||||||
/// Send a message to a thread waiting to receive on this mailbox. If no threads
|
|
||||||
/// are currently trying to receive, block the current thread.
|
|
||||||
/// \arg msg The mailbox::message data structure to send
|
|
||||||
void send(message *msg);
|
|
||||||
|
|
||||||
/// Send a message to a thread waiting to receive on this mailbox, and block the
|
/// Send a message to a thread waiting to receive on this mailbox, and block the
|
||||||
/// current thread awaiting a response. The response will be placed in the message
|
/// current thread awaiting a response. The response will be placed in the message
|
||||||
/// object provided.
|
/// object provided.
|
||||||
|
|||||||
@@ -69,63 +69,6 @@ prep_receive(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_status_t
|
|
||||||
mailbox_send(
|
|
||||||
mailbox *self,
|
|
||||||
uint64_t tag,
|
|
||||||
uint64_t subtag,
|
|
||||||
j6_handle_t * handles,
|
|
||||||
size_t handle_count)
|
|
||||||
{
|
|
||||||
mailbox::message *msg = new mailbox::message;
|
|
||||||
|
|
||||||
j6_status_t s = prep_send(msg,
|
|
||||||
tag, subtag,
|
|
||||||
handles, handle_count);
|
|
||||||
|
|
||||||
if (s != j6_status_ok) {
|
|
||||||
delete msg;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->send(msg);
|
|
||||||
return j6_status_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
j6_status_t
|
|
||||||
mailbox_receive(
|
|
||||||
mailbox *self,
|
|
||||||
uint64_t *tag,
|
|
||||||
uint64_t *subtag,
|
|
||||||
j6_handle_t *handles,
|
|
||||||
size_t *handle_count,
|
|
||||||
uint16_t *reply_tag,
|
|
||||||
uint64_t flags)
|
|
||||||
{
|
|
||||||
if (*handle_count < mailbox::max_handle_count)
|
|
||||||
return j6_err_insufficient;
|
|
||||||
|
|
||||||
mailbox::message *msg = nullptr;
|
|
||||||
|
|
||||||
bool block = flags & j6_mailbox_block;
|
|
||||||
if (!self->receive(msg, block)) {
|
|
||||||
// No message received
|
|
||||||
return self->closed() ? j6_status_closed :
|
|
||||||
!block ? j6_status_would_block :
|
|
||||||
j6_err_unexpected;
|
|
||||||
}
|
|
||||||
|
|
||||||
prep_receive(msg,
|
|
||||||
tag, subtag, reply_tag,
|
|
||||||
handles, handle_count);
|
|
||||||
|
|
||||||
if (*reply_tag == 0)
|
|
||||||
delete msg;
|
|
||||||
return j6_status_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
mailbox_call(
|
mailbox_call(
|
||||||
mailbox *self,
|
mailbox *self,
|
||||||
@@ -159,34 +102,8 @@ mailbox_call(
|
|||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
mailbox_respond(
|
mailbox_respond(
|
||||||
mailbox *self,
|
|
||||||
uint64_t tag,
|
|
||||||
uint64_t subtag,
|
|
||||||
j6_handle_t * handles,
|
|
||||||
size_t handle_count,
|
|
||||||
uint16_t reply_tag)
|
|
||||||
{
|
|
||||||
mailbox::replyer reply = self->reply(reply_tag);
|
|
||||||
if (!reply.valid())
|
|
||||||
return j6_err_invalid_arg;
|
|
||||||
|
|
||||||
j6_status_t s = prep_send(reply.msg, tag, subtag,
|
|
||||||
handles, handle_count);
|
|
||||||
|
|
||||||
if (s != j6_status_ok) {
|
|
||||||
reply.error(s);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return j6_status_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
j6_status_t
|
|
||||||
mailbox_respond_receive(
|
|
||||||
mailbox *self,
|
mailbox *self,
|
||||||
uint64_t *tag,
|
uint64_t *tag,
|
||||||
uint64_t *subtag,
|
uint64_t *subtag,
|
||||||
@@ -196,17 +113,43 @@ mailbox_respond_receive(
|
|||||||
uint16_t *reply_tag,
|
uint16_t *reply_tag,
|
||||||
uint64_t flags)
|
uint64_t flags)
|
||||||
{
|
{
|
||||||
j6_status_t s = mailbox_respond(self, *tag, *subtag, handles, handles_in, *reply_tag);
|
if (*reply_tag) {
|
||||||
if (s != j6_status_ok)
|
mailbox::replyer reply = self->reply(*reply_tag);
|
||||||
return s;
|
if (!reply.valid())
|
||||||
|
return j6_err_invalid_arg;
|
||||||
|
|
||||||
s = mailbox_receive(self, tag, subtag, handles, handle_count, reply_tag, flags);
|
j6_status_t s = prep_send(reply.msg, *tag, *subtag,
|
||||||
if (s != j6_status_ok)
|
handles, handles_in);
|
||||||
|
|
||||||
|
if (s != j6_status_ok) {
|
||||||
|
reply.error(s);
|
||||||
return s;
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (*handle_count < mailbox::max_handle_count)
|
||||||
|
return j6_err_insufficient;
|
||||||
|
|
||||||
|
mailbox::message *msg = nullptr;
|
||||||
|
|
||||||
|
bool block = flags & j6_mailbox_block;
|
||||||
|
if (!self->receive(msg, block)) {
|
||||||
|
// No message received
|
||||||
|
return self->closed() ? j6_status_closed :
|
||||||
|
!block ? j6_status_would_block :
|
||||||
|
j6_err_unexpected;
|
||||||
|
}
|
||||||
|
|
||||||
|
prep_receive(msg,
|
||||||
|
tag, subtag, reply_tag,
|
||||||
|
handles, handle_count);
|
||||||
|
|
||||||
|
if (*reply_tag == 0)
|
||||||
|
delete msg;
|
||||||
|
|
||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace syscalls
|
} // namespace syscalls
|
||||||
|
|||||||
@@ -23,22 +23,26 @@ service_locator_start(j6_handle_t mb)
|
|||||||
// TODO: This should be a multimap
|
// TODO: This should be a multimap
|
||||||
util::node_map<uint64_t, handle_entry> services;
|
util::node_map<uint64_t, handle_entry> services;
|
||||||
|
|
||||||
uint64_t tag;
|
uint64_t tag = 0;
|
||||||
uint64_t subtag;
|
uint64_t subtag = 0;
|
||||||
uint16_t reply_tag;
|
uint16_t reply_tag = 0;
|
||||||
|
|
||||||
j6_handle_t handles[10];
|
j6_handle_t handles[10] = {0};
|
||||||
size_t handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
const size_t handles_capacity = sizeof(handles)/sizeof(j6_handle_t);
|
||||||
|
size_t handles_count = 0;
|
||||||
j6_status_t s = j6_mailbox_receive(mb,
|
|
||||||
&tag, &subtag,
|
|
||||||
handles, &handles_count,
|
|
||||||
&reply_tag,
|
|
||||||
j6_mailbox_block);
|
|
||||||
|
|
||||||
uint64_t proto_id;
|
uint64_t proto_id;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
size_t handles_in = handles_count;
|
||||||
|
handles_count = handles_capacity;
|
||||||
|
|
||||||
|
j6_status_t s = j6_mailbox_respond(mb,
|
||||||
|
&tag, &subtag,
|
||||||
|
handles, &handles_count,
|
||||||
|
handles_in, &reply_tag,
|
||||||
|
j6_mailbox_block);
|
||||||
|
|
||||||
handle_entry *found = nullptr;
|
handle_entry *found = nullptr;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
@@ -82,14 +86,5 @@ service_locator_start(j6_handle_t mb)
|
|||||||
handles_count = 0;
|
handles_count = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t handles_in = handles_count;
|
|
||||||
handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
|
||||||
|
|
||||||
s = j6_mailbox_respond_receive(mb,
|
|
||||||
&tag, &subtag,
|
|
||||||
handles, &handles_count, handles_in,
|
|
||||||
&reply_tag,
|
|
||||||
j6_mailbox_block);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user