Switching now works with provided bindings.

master
Philippe PITTOLI 2024-06-16 16:02:03 +02:00
parent 8e889ef242
commit 18a77fa2ef
10 changed files with 39 additions and 27 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
zig-cache
zig-out
.zig-cache
docs
*.swp

View File

@ -24,5 +24,6 @@ See the [dedicated repository][examples].
LibIPC reached a stable state and is usable.
Performance is fine for most projects, but can be largely improved.
The `poll` syscall is used instead of more recent and *faster* syscalls (`epoll`, `kqueue`, etc.).
[examples]: https://git.baguette.netlib.re/Baguette/libipc-examples

View File

@ -1,6 +1,6 @@
const std = @import("std");
const VERSION = "0.1.2";
const VERSION = "0.2.0";
// Although this function looks imperative, note that its job is to
// declaratively construct a build graph that will be executed by an external

2
ipc.pc
View File

@ -3,6 +3,6 @@ libdir=/usr/local/lib
Name: LibIPC
Description: The simplest Inter Process Communication library
Version: 0.1.2
Version: 0.2.0
Libs: -L${libdir} -lipc
Cflags: -I${includedir}

View File

@ -48,7 +48,7 @@ serve-doc:
darkhttpd docs/ --addr $(DOC_HTTPD_ADDR) --port $(DOC_HTTPD_PORT) --log $(DOC_HTTPD_ACCESS_LOGS)
PACKAGE ?= libipc
VERSION ?= 0.1.2
VERSION ?= 0.2.0
PKG = $(PACKAGE)-$(VERSION)
dist-dir:
[ -d $(PKG) ] || ln -s . $(PKG)

View File

@ -107,7 +107,10 @@ export fn ipc_wait_event(ctx: *Context, t: *u8, index: *usize, originfd: *i32, n
var writer = fbs.writer();
_ = writer.write(m.payload) catch return -4;
buflen.* = m.payload.len;
m.deinit();
switch (event.t) {
.SWITCH_RX => {},
else => m.deinit(),
}
} else {
buflen.* = 0;
}

View File

@ -1,17 +1,11 @@
const std = @import("std");
const testing = std.testing;
// const DEBUG = @import("./hexdump.zig");
const net = std.net;
const os = std.os;
const fmt = std.fmt;
const c = std.c;
const posix = std.posix;
// const print = std.debug.print;
// TODO: to remove once PR https://github.com/ziglang/zig/pull/14639 is accepted.
pub extern "c" fn umask(mode: c.mode_t) c.mode_t;
const log = std.log.scoped(.libipc_context);
const receive_fd = @import("./exchange-fd.zig").receive_fd;
@ -35,7 +29,6 @@ pub const PollFD = std.ArrayList(posix.pollfd);
pub const IPC_HEADER_SIZE = 4; // Size (4 bytes) then content.
pub const IPC_BASE_SIZE = 100000; // 100 KB, plenty enough space for messages
pub const IPC_MAX_MESSAGE_SIZE = IPC_BASE_SIZE - IPC_HEADER_SIZE;
pub const IPC_VERSION = 1;
// Context of the whole networking state.
pub const Context = struct {
@ -66,8 +59,8 @@ pub const Context = struct {
};
// Allow mkdir to create a directory with 0o770 permissions.
const previous_mask = umask(0o007);
defer _ = umask(previous_mask);
const previous_mask = c.umask(0o007);
defer _ = c.umask(previous_mask);
// Create the run directory, where all UNIX sockets will be.
posix.mkdir(rundir, 0o0770) catch |err| switch (err) {
@ -80,7 +73,12 @@ pub const Context = struct {
},
};
return Self{ .rundir = rundir, .connections = Connections.init(allocator), .pollfd = PollFD.init(allocator), .tx = Messages.init(allocator), .switchdb = SwitchDB.init(allocator), .allocator = allocator };
return Self{ .rundir = rundir
, .connections = Connections.init(allocator)
, .pollfd = PollFD.init(allocator)
, .tx = Messages.init(allocator)
, .switchdb = SwitchDB.init(allocator)
, .allocator = allocator };
}
pub fn deinit(self: *Self) void {
@ -264,8 +262,8 @@ pub const Context = struct {
// Allow to create a unix socket with the right permissions.
// Group should include write permissions.
const previous_mask = umask(0o117);
defer _ = umask(previous_mask);
const previous_mask = c.umask(0o117);
defer _ = c.umask(previous_mask);
// Remove the old UNIX socket.
posix.unlink(path) catch |err| switch (err) {
@ -297,12 +295,6 @@ pub const Context = struct {
_ = try m.write(writer); // returns paylen
_ = try stream.write(fbs.getWritten());
// var hexbuf: [2000]u8 = undefined;
// var hexfbs = std.io.fixedBufferStream(&hexbuf);
// var hexwriter = hexfbs.writer();
// try DEBUG.hexdump(hexwriter, "MSG SENT", fbs.getWritten());
// print("{s}\n", .{hexfbs.getWritten()});
}
pub fn schedule(self: *Self, m: Message) !void {

View File

@ -72,6 +72,17 @@ pub fn hexdump(stream: anytype, header: []const u8, buffer: []const u8) std.posi
try stream.writeAll("\n");
}
/// Debug function: print some bytes' hexdump on standard output.
pub fn print_hex(title: []const u8, buffer : []const u8) !void
{
const stdout = std.io.getStdOut().writer();
var hexbuf: [100_000]u8 = undefined;
var hexfbs = std.io.fixedBufferStream(&hexbuf);
const hexwriter = hexfbs.writer();
try hexdump(hexwriter, title, buffer);
try stdout.print("{s}\n", .{hexfbs.getWritten()});
}
const print = std.debug.print;
test "36-byte hexdump test" {

View File

@ -5,6 +5,7 @@ const fmt = std.fmt;
const print_eq = @import("./util.zig").print_eq;
const payload_header_length = 4;
pub const Messages = std.ArrayList(Message);
pub const Message = struct {
@ -28,17 +29,17 @@ pub const Message = struct {
var reader = fbs.reader();
const msg_len = try reader.readInt(u32, .big);
if (msg_len > buffer.len - 4) {
if (msg_len > buffer.len - payload_header_length) {
return error.wrongMessageLength;
}
const msg_payload = buffer[4 .. 4 + msg_len];
const msg_payload = buffer[payload_header_length .. payload_header_length + msg_len];
return try Message.init(fd, allocator, msg_payload);
}
pub fn write(self: Self, writer: anytype) !usize {
try writer.writeInt(u32, @as(u32, @truncate(self.payload.len)), .big);
return 4 + try writer.write(self.payload);
return payload_header_length + try writer.write(self.payload);
}
pub fn format(self: Self, comptime _: []const u8, _: fmt.FormatOptions, out_stream: anytype) !void {

View File

@ -40,10 +40,12 @@ pub const SwitchDB = struct {
const Self = @This();
db: std.AutoArrayHashMap(i32, ManagedConnection),
allocator: std.mem.Allocator,
pub fn init(allocator: Allocator) Self {
return Self{
.db = std.AutoArrayHashMap(i32, ManagedConnection).init(allocator),
.allocator = allocator,
};
}
@ -87,9 +89,10 @@ pub const SwitchDB = struct {
},
CBEventType.NO_ERROR => {
// TODO: read message
// TODO: better allocator?
// TODO: better errors?
const message: Message = Message.read(managedconnection.dest, buffer[0..message_size], std.heap.c_allocator) catch {
const message: Message = Message.read(managedconnection.dest
, buffer[0..message_size]
, self.allocator) catch {
return error.generic;
};
return message;