Skip to content

Commit

Permalink
m
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Mar 10, 2024
1 parent 2cfeaeb commit 06d5ab7
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 0 deletions.
2 changes: 2 additions & 0 deletions meta/plugins/start/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def generateSystem(img: image.Image) -> None:

img.install("grund-system", "skift-x86_64")
img.install("grund-device", "skift-x86_64")
img.install("grund-echo", "skift-x86_64")
img.install("grund-test", "skift-x86_64")
img.install("hideo-shell", "skift-x86_64")
img.install("skift-branding", "skift-x86_64")
img.install("skift-wallpapers", "skift-x86_64")
Expand Down
34 changes: 34 additions & 0 deletions src/libs/karm-ipc/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <karm-base/func.h>
#include <karm-io/bscan.h>
#include <karm-io/pack.h>
#include <karm-logger/logger.h>
#include <karm-sys/context.h>
#include <karm-sys/socket.h>

namespace Karm::Ipc {

struct Null {
template <typename I, u64 uid, typename R, typename... Args>
auto invoke(Args &&...) {
return R{};
}
};

template <typename T>
concept Interface = requires(T &t) {
{ T::_UID } -> Meta::Convertible<long long>;
{ T::_NAME } -> Meta::Convertible<char const *>;
typename T::template _Client<Null>;
};

struct Message {
static constexpr auto ERROR = 0xffffffffffffffff;
static constexpr auto END = 0xfffffffffffffffe;

Buf<Byte> data;
Buf<Sys::Handle> handles;
};

} // namespace Karm::Ipc
48 changes: 48 additions & 0 deletions src/libs/karm-ipc/client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include "base.h"

namespace Karm::Ipc {

struct Transport {
struct _Job {
usize _id = 0;
virtual ~_Job() = default;
virtual void submit(Sys::IpcConnection &) = 0;
virtual void complete(Sys::IpcConnection &) = 0;
};
Sys::IpcConnection _con;
usize _id = 0;
Map<usize, Strong<_Job>> _jobs;

Transport(Sys::IpcConnection con)
: _con(std::move(con)) {}

void submit(Strong<_Job> job) {
job->_id = _id++;
_jobs.put(job->_id, std::move(job));
job->submit(_con);
}

template <typename I, usize UID, typename Ret, typename... Args>
Ret invoke(Args...) {
struct Job : public _Job {
void submit(Sys::IpcConnection &) override {}
void complete(Sys::IpcConnection &) override {}
};
Io::BufferWriter reqData;
Io::BEmit reqEmit{reqData};

co_trya$(_con.sendAsync(reqData.bytes(), {}));

co_return {};
}
};

template <Interface T>
Async::Task<Strong<T>> connectAsync(Url::Url url) {
auto con = co_try$(Sys::IpcConnection::connect(url));
co_return Ok(makeStrong<typename T::template _Client<Transport>>(con));
}

} // namespace Karm::Ipc
10 changes: 10 additions & 0 deletions src/libs/karm-ipc/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "karm-ipc",
"type": "lib",
"description": "Inter-process communication",
"requires": [
"karm-sys",
"karm-base"
]
}
79 changes: 79 additions & 0 deletions src/libs/karm-ipc/server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include "base.h"

namespace Karm::Ipc {

Async::Task<> serveLoop(Sys::IpcConnection &con, Func<Async::Task<>(Io::BScan &req, Io::BEmit &resp)> handle) {
Buf<Byte> reqBuf;
Buf<Sys::Handle> reqHnds;
reqBuf.resize(Sys::IpcConnection::MAX_BUF_SIZE);
reqHnds.resize(Sys::IpcConnection::MAX_HND_SIZE);

while (true) {
[[maybe_unused]] auto [nbytes, _] = co_trya$(con.recvAsync(reqBuf, reqHnds));
logDebug("Got {} bytes from the client", nbytes);

Io::BScan reqScan{sub(reqBuf, 0, nbytes)};

Io::BufferWriter respData;
Io::BEmit respEmit{respData};

co_trya$(con.sendAsync(respData.bytes(), {}));
}
}

struct Handler {
u64 mid;
Io::BScan &req;
Io::BEmit &resp;

template <typename... Args>
Async::Task<> call(auto invoke) {
logDebug("Handling message id: {016x}", mid);
auto args = Io::unpack<Tuple<Args...>>(req);
auto ret = co_await args.apply(invoke);
Io::pack(resp, ret);
co_return Ok();
}

Async::Task<> error() {
logWarn("Invalid message id: {016x}", mid);
resp.writeU64be(Message::ERROR);
resp.writeU64be(Message::END);
co_return Ok();
}
};

template <Interface I>
Async::Task<> handleConnection(Sys::IpcConnection con) {
I i;
co_return co_trya$(serveLoop(con, [&](Io::BScan &req, Io::BEmit &resp) -> Async::Task<> {
u64 iId = req.nextU64le();
u64 mId = req.nextU64le();

if (iId != I::_UID) {
logWarn("Invalid interface id: {016x}", iId);
resp.writeU64be(Message::ERROR);
resp.writeU64be(Message::END);
}

logDebug("Handling interface id: {016x}", iId);

Handler handler{mId, req, resp};
co_trya$(i._dispatch(handler));
resp.writeU64le(Message::END);

co_return Ok();
}));
}

template <Interface I>
Async::Task<> serveAsync(Sys::Ctx &ctx, Url::Url url) {
auto listener = co_try$(Sys::IpcListener::listen(url));
logInfo("Serving {} on {}...", I::_NAME, url);
while (true)
Async::detach(handleConnection<I>(co_trya$(listener.acceptAsync())));
}

} // namespace Karm::Ipc
46 changes: 46 additions & 0 deletions src/srvs/grund-echo/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once
// Generated by chatty from src/srvs/grund-echo/api.idl
// DO NOT EDIT
#include <karm-base/async.h>
namespace Grund::Echo {

struct IEcho {
static constexpr auto _UID = 0xd31ef811301c6b41;
static constexpr auto _NAME = "Echo";

template <typename T>
struct _Client;

auto _dispatch(auto &);

virtual ~IEcho() = default;

static constexpr auto pingAsync_UID = 0x0b0a4b8aec6e280a;
virtual Async::Task<String> pingAsync(String val) = 0;
};

template <typename T>
struct IEcho::_Client : public IEcho {
T _t;

_Client(T t) : _t{t} {}

Async::Task<String> pingAsync(String val) {
return _t.template invoke<IEcho, pingAsync_UID, Async::Task<String>, String>(val);
}
};

auto IEcho::_dispatch(auto &o) {
switch (o.mid) {

case pingAsync_UID:
return o.template call<String>([&]<typename... Args>(Args &&...args) {
return pingAsync(std::forward<Args>(args)...);
});

default:
return o.error();
}
}

} // namespace Grund::Echo
7 changes: 7 additions & 0 deletions src/srvs/grund-echo/api.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Grund::Echo

include "karm-base/async.h"

Echo {
pingAsync(val : String) -> Async::Task<String>,
}
9 changes: 9 additions & 0 deletions src/srvs/grund-echo/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "grund-echo-base",
"type": "lib",
"description": "Simple echo service",
"requires": [
"karm-sys"
]
}
20 changes: 20 additions & 0 deletions src/srvs/grund-echo/srv/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <karm-ipc/server.h>
#include <karm-logger/logger.h>
#include <karm-sys/entry-async.h>

#include "../api.h"

namespace Grund::Echo {

struct EchoServer : public IEcho {
Async::Task<String> pingAsync(String val) override {
logInfo("Got message: {}", val);
co_return Ok(Io::toUpperCase(val));
}
};

} // namespace Grund::Echo

Async::Task<> entryPointAsync(Sys::Ctx &ctx) {
return Ipc::serveAsync<Grund::Echo::EchoServer>(ctx, "ipc:/echo"_url);
}
10 changes: 10 additions & 0 deletions src/srvs/grund-echo/srv/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "grund-echo",
"type": "exe",
"description": "Simple echo service",
"requires": [
"karm-sys",
"grund-echo-base"
]
}
11 changes: 11 additions & 0 deletions src/srvs/grund-test/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <grund-echo/api.h>
#include <karm-ipc/client.h>
#include <karm-logger/logger.h>
#include <karm-sys/entry-async.h>

Async::Task<> entryPointAsync(Sys::Ctx &) {
auto client = co_trya$(Ipc::connectAsync<Grund::Echo::IEcho>("ipc:/echo"_url));
auto message = co_trya$(client->pingAsync("Hello, world!"));
logInfo("Got message: {}", message);
co_return Ok();
}
9 changes: 9 additions & 0 deletions src/srvs/grund-test/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "grund-test",
"type": "exe",
"description": "Simple test service",
"requires": [
"karm-sys"
]
}

0 comments on commit 06d5ab7

Please sign in to comment.