mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kernel] Add channel objects
Add the channel object for sending messages between threads. Currently no good of passing channels to other threads, but global variables in a single process work. Currently channels are slow and do double copies, need to refine more. Tags: ipc
This commit is contained in:
70
src/kernel/objects/channel.cpp
Normal file
70
src/kernel/objects/channel.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "kutil/assert.h"
|
||||
|
||||
#include "objects/channel.h"
|
||||
|
||||
channel::channel() :
|
||||
m_len(0),
|
||||
m_capacity(0),
|
||||
m_data(nullptr),
|
||||
kobject(kobject::type::channel, j6_signal_channel_can_send)
|
||||
{
|
||||
}
|
||||
|
||||
channel::~channel()
|
||||
{
|
||||
kutil::kfree(m_data);
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
channel::enqueue(size_t len, void *data)
|
||||
{
|
||||
// TODO: Make this thread safe!
|
||||
if (closed())
|
||||
return j6_status_closed;
|
||||
|
||||
if (!can_send())
|
||||
return j6_err_not_ready;
|
||||
|
||||
if (m_capacity < len) {
|
||||
kutil::kfree(m_data);
|
||||
m_data = kutil::kalloc(len);
|
||||
m_capacity = len;
|
||||
kassert(m_data, "Failed to allocate memory to copy channel message");
|
||||
}
|
||||
|
||||
m_len = len;
|
||||
kutil::memcpy(m_data, data, len);
|
||||
assert_signal(j6_signal_channel_can_recv);
|
||||
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
channel::dequeue(size_t *len, void *data)
|
||||
{
|
||||
// TODO: Make this thread safe!
|
||||
if (closed())
|
||||
return j6_status_closed;
|
||||
|
||||
if (!can_receive())
|
||||
return j6_err_not_ready;
|
||||
|
||||
if (!len)
|
||||
return j6_err_invalid_arg;
|
||||
|
||||
if (*len < m_len)
|
||||
return j6_err_insufficient;
|
||||
|
||||
kutil::memcpy(data, m_data, m_len);
|
||||
*len = m_len;
|
||||
assert_signal(j6_signal_channel_can_send);
|
||||
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
channel::on_no_handles()
|
||||
{
|
||||
kobject::on_no_handles();
|
||||
delete this;
|
||||
}
|
||||
49
src/kernel/objects/channel.h
Normal file
49
src/kernel/objects/channel.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
/// \file channel.h
|
||||
/// Definition of channel objects and related functions
|
||||
|
||||
#include "j6/signals.h"
|
||||
#include "objects/kobject.h"
|
||||
|
||||
/// Channels are bi-directional means of sending messages
|
||||
class channel :
|
||||
public kobject
|
||||
{
|
||||
public:
|
||||
channel();
|
||||
virtual ~channel();
|
||||
|
||||
/// Check if the channel has space for a message to be sent
|
||||
inline bool can_send() const { return check_signal(j6_signal_channel_can_send); }
|
||||
|
||||
/// Check if the channel has a message wiating already
|
||||
inline bool can_receive() const { return check_signal(j6_signal_channel_can_recv); }
|
||||
|
||||
/// Put a message into the channel
|
||||
/// \arg len Length of data, in bytes
|
||||
/// \arg data Pointer to the message data
|
||||
/// \returns j6_status_ok on success
|
||||
j6_status_t enqueue(size_t len, void *data);
|
||||
|
||||
/// Get a message from the channel, copied into a provided buffer
|
||||
/// \arg len On input, the size of the provided buffer. On output,
|
||||
/// the size of the message copied into the buffer.
|
||||
/// \arg data Pointer to the buffer
|
||||
/// \returns j6_status_ok on success
|
||||
j6_status_t dequeue(size_t *len, void *data);
|
||||
|
||||
/// Mark this channel as closed, all future calls to enqueue or
|
||||
/// dequeue messages will fail with j6_status_closed.
|
||||
inline void close() { assert_signal(j6_signal_channel_closed); }
|
||||
|
||||
/// Check if this channel has been closed
|
||||
inline bool closed() { return check_signal(j6_signal_channel_closed); }
|
||||
|
||||
protected:
|
||||
virtual void on_no_handles() override;
|
||||
|
||||
private:
|
||||
size_t m_len;
|
||||
size_t m_capacity;
|
||||
void *m_data;
|
||||
};
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
|
||||
event,
|
||||
eventpair,
|
||||
channel,
|
||||
|
||||
vms,
|
||||
vmo,
|
||||
@@ -55,6 +56,10 @@ public:
|
||||
/// \arg s The set of signals to deassert
|
||||
void deassert_signal(j6_signal_t s);
|
||||
|
||||
/// Check if the given signals are set on this object
|
||||
/// \arg s The set of signals to check
|
||||
inline bool check_signal(j6_signal_t s) const { return (m_signals & s) == s; }
|
||||
|
||||
/// Increment the handle refcount
|
||||
inline void handle_retain() { ++m_handle_count; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user