This change finally adds capabilities to handles. Included changes: - j6_handle_t is now again 64 bits, with the highest 8 bits being a type code, and the next highest 24 bits being the capability mask, so that programs can check type/caps without calling the kernel. - The definitions grammar now includes a `capabilities [ ]` section on objects, to list what capabilities are relevant. - j6/caps.h is auto-generated from object capability lists - init_libj6 again sets __handle_self and __handle_sys, this is a bit of a hack. - A new syscall, j6_handle_list, will return the list of existing handles owned by the calling process. - syscall_verify.cpp.cog now actually checks that the needed capabilities exist on handles before allowing the call.
82 lines
2.5 KiB
C++
82 lines
2.5 KiB
C++
#pragma once
|
|
/// \file endpoint.h
|
|
/// Definition of endpoint kobject types
|
|
|
|
#include <j6/caps.h>
|
|
#include <j6/signals.h>
|
|
#include <util/spinlock.h>
|
|
#include <util/vector.h>
|
|
|
|
#include "objects/kobject.h"
|
|
|
|
namespace obj {
|
|
|
|
/// Endpoints are objects that enable synchronous message-passing IPC
|
|
class endpoint :
|
|
public kobject
|
|
{
|
|
public:
|
|
/// Capabilities on a newly constructed endpoint handle
|
|
constexpr static j6_cap_t creation_caps = j6_cap_endpoint_all;
|
|
|
|
endpoint();
|
|
virtual ~endpoint();
|
|
|
|
static constexpr kobject::type type = kobject::type::endpoint;
|
|
|
|
/// Close the endpoint, waking all waiting processes with an error
|
|
virtual void close() override;
|
|
|
|
/// Check if the endpoint has space for a message to be sent
|
|
inline bool can_send() const { return check_signal(j6_signal_endpoint_can_send); }
|
|
|
|
/// Check if the endpoint has a message wiating already
|
|
inline bool can_receive() const { return check_signal(j6_signal_endpoint_can_recv); }
|
|
|
|
/// Send a message to a thread waiting to receive on this endpoint. If no threads
|
|
/// are currently trying to receive, block the current thread.
|
|
/// \arg tag The application-specified message tag
|
|
/// \arg data The message data
|
|
/// \arg len The size in bytes of the message
|
|
/// \returns j6_status_ok on success
|
|
j6_status_t send(j6_tag_t tag, const void *data, size_t data_len);
|
|
|
|
/// Receive a message from a thread waiting to send on this endpoint. If no threads
|
|
/// are currently trying to send, block the current thread.
|
|
/// \arg tag [in] The sender-specified message tag
|
|
/// \arg len [in] The size in bytes of the buffer [out] Number of bytes in the message
|
|
/// \arg data Buffer for copying message data into
|
|
/// \arg timeout Receive timeout in nanoseconds
|
|
/// \returns j6_status_ok on success
|
|
j6_status_t receive(j6_tag_t *tag, void *data, size_t *data_len, uint64_t timeout = 0);
|
|
|
|
/// Give the listener on the endpoint a message that a bound IRQ has been signalled
|
|
/// \arg irq The IRQ that caused this signal
|
|
void signal_irq(unsigned irq);
|
|
|
|
private:
|
|
struct thread_data
|
|
{
|
|
thread *th;
|
|
union {
|
|
const void *data;
|
|
void *buffer;
|
|
};
|
|
union {
|
|
j6_tag_t *tag_p;
|
|
j6_tag_t tag;
|
|
};
|
|
union {
|
|
size_t *len_p;
|
|
size_t len;
|
|
};
|
|
};
|
|
|
|
j6_status_t do_message_copy(const thread_data &sender, thread_data &receiver);
|
|
|
|
util::spinlock m_lock;
|
|
util::vector<thread_data> m_blocked;
|
|
};
|
|
|
|
} // namespace obj
|