diff --git a/definitions/objects/mailbox.def b/definitions/objects/mailbox.def index a48c143..1250036 100644 --- a/definitions/objects/mailbox.def +++ b/definitions/objects/mailbox.def @@ -1,5 +1,5 @@ -# Mailboxes are objects that enable synchronous or asynchronous -# IPC via short message-passing of bytes and handles. +# Mailboxes are objects that enable synchronous IPC via short message-passing +# of tagged handles. object mailbox : object { uid 99934ad04ece1e07 @@ -13,23 +13,6 @@ object mailbox : object { method create [constructor] 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 # response is sent. Note that getting this response # does not require the receive capability. @@ -39,19 +22,11 @@ object mailbox : object { 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 # message to arrive. Note that this does not require the send - # capability. - method respond_receive [cap:receive] { + # capability. A reply tag of 0 skips the reply and goes directly + # to waiting for a new message. + method respond [cap:receive] { param tag uint64 [inout] param subtag uint64 [inout] param handles ref object [inout list zero_ok] diff --git a/src/kernel/objects/mailbox.cpp b/src/kernel/objects/mailbox.cpp index e358b29..464954e 100644 --- a/src/kernel/objects/mailbox.cpp +++ b/src/kernel/objects/mailbox.cpp @@ -45,18 +45,6 @@ mailbox::close() 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 mailbox::call(message *msg) { diff --git a/src/kernel/objects/mailbox.h b/src/kernel/objects/mailbox.h index be09bdc..f913446 100644 --- a/src/kernel/objects/mailbox.h +++ b/src/kernel/objects/mailbox.h @@ -39,11 +39,6 @@ public: /// Check if the mailbox has been 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 /// current thread awaiting a response. The response will be placed in the message /// object provided. diff --git a/src/kernel/syscalls/mailbox.cpp b/src/kernel/syscalls/mailbox.cpp index a367f94..dc25b06 100644 --- a/src/kernel/syscalls/mailbox.cpp +++ b/src/kernel/syscalls/mailbox.cpp @@ -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 mailbox_call( mailbox *self, @@ -159,34 +102,8 @@ mailbox_call( return j6_status_ok; } - j6_status_t 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, uint64_t *tag, uint64_t *subtag, @@ -196,17 +113,43 @@ mailbox_respond_receive( uint16_t *reply_tag, uint64_t flags) { - j6_status_t s = mailbox_respond(self, *tag, *subtag, handles, handles_in, *reply_tag); - if (s != j6_status_ok) - return s; + if (*reply_tag) { + mailbox::replyer reply = self->reply(*reply_tag); + if (!reply.valid()) + return j6_err_invalid_arg; - s = mailbox_receive(self, tag, subtag, handles, handle_count, reply_tag, flags); - if (s != j6_status_ok) - return s; + j6_status_t s = prep_send(reply.msg, *tag, *subtag, + handles, handles_in); + + if (s != j6_status_ok) { + reply.error(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; } - } // namespace syscalls diff --git a/src/user/srv.init/service_locator.cpp b/src/user/srv.init/service_locator.cpp index 60cf67d..a28f8f9 100644 --- a/src/user/srv.init/service_locator.cpp +++ b/src/user/srv.init/service_locator.cpp @@ -23,22 +23,26 @@ service_locator_start(j6_handle_t mb) // TODO: This should be a multimap util::node_map services; - uint64_t tag; - uint64_t subtag; - uint16_t reply_tag; + uint64_t tag = 0; + uint64_t subtag = 0; + uint16_t reply_tag = 0; - j6_handle_t handles[10]; - size_t handles_count = sizeof(handles)/sizeof(j6_handle_t); - - j6_status_t s = j6_mailbox_receive(mb, - &tag, &subtag, - handles, &handles_count, - &reply_tag, - j6_mailbox_block); + j6_handle_t handles[10] = {0}; + const size_t handles_capacity = sizeof(handles)/sizeof(j6_handle_t); + size_t handles_count = 0; uint64_t proto_id; 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; switch (tag) { @@ -82,14 +86,5 @@ service_locator_start(j6_handle_t mb) handles_count = 0; 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); } }