Switching now works with provided bindings.
parent
8e889ef242
commit
18a77fa2ef
|
@ -1,4 +1,5 @@
|
||||||
zig-cache
|
zig-cache
|
||||||
zig-out
|
zig-out
|
||||||
|
.zig-cache
|
||||||
docs
|
docs
|
||||||
*.swp
|
*.swp
|
||||||
|
|
|
@ -24,5 +24,6 @@ See the [dedicated repository][examples].
|
||||||
|
|
||||||
LibIPC reached a stable state and is usable.
|
LibIPC reached a stable state and is usable.
|
||||||
Performance is fine for most projects, but can be largely improved.
|
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
|
[examples]: https://git.baguette.netlib.re/Baguette/libipc-examples
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const std = @import("std");
|
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
|
// Although this function looks imperative, note that its job is to
|
||||||
// declaratively construct a build graph that will be executed by an external
|
// declaratively construct a build graph that will be executed by an external
|
||||||
|
|
2
ipc.pc
2
ipc.pc
|
@ -3,6 +3,6 @@ libdir=/usr/local/lib
|
||||||
|
|
||||||
Name: LibIPC
|
Name: LibIPC
|
||||||
Description: The simplest Inter Process Communication library
|
Description: The simplest Inter Process Communication library
|
||||||
Version: 0.1.2
|
Version: 0.2.0
|
||||||
Libs: -L${libdir} -lipc
|
Libs: -L${libdir} -lipc
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
2
makefile
2
makefile
|
@ -48,7 +48,7 @@ serve-doc:
|
||||||
darkhttpd docs/ --addr $(DOC_HTTPD_ADDR) --port $(DOC_HTTPD_PORT) --log $(DOC_HTTPD_ACCESS_LOGS)
|
darkhttpd docs/ --addr $(DOC_HTTPD_ADDR) --port $(DOC_HTTPD_PORT) --log $(DOC_HTTPD_ACCESS_LOGS)
|
||||||
|
|
||||||
PACKAGE ?= libipc
|
PACKAGE ?= libipc
|
||||||
VERSION ?= 0.1.2
|
VERSION ?= 0.2.0
|
||||||
PKG = $(PACKAGE)-$(VERSION)
|
PKG = $(PACKAGE)-$(VERSION)
|
||||||
dist-dir:
|
dist-dir:
|
||||||
[ -d $(PKG) ] || ln -s . $(PKG)
|
[ -d $(PKG) ] || ln -s . $(PKG)
|
||||||
|
|
|
@ -107,7 +107,10 @@ export fn ipc_wait_event(ctx: *Context, t: *u8, index: *usize, originfd: *i32, n
|
||||||
var writer = fbs.writer();
|
var writer = fbs.writer();
|
||||||
_ = writer.write(m.payload) catch return -4;
|
_ = writer.write(m.payload) catch return -4;
|
||||||
buflen.* = m.payload.len;
|
buflen.* = m.payload.len;
|
||||||
m.deinit();
|
switch (event.t) {
|
||||||
|
.SWITCH_RX => {},
|
||||||
|
else => m.deinit(),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buflen.* = 0;
|
buflen.* = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
// const DEBUG = @import("./hexdump.zig");
|
|
||||||
const net = std.net;
|
const net = std.net;
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
const fmt = std.fmt;
|
const fmt = std.fmt;
|
||||||
const c = std.c;
|
const c = std.c;
|
||||||
const posix = std.posix;
|
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 log = std.log.scoped(.libipc_context);
|
||||||
|
|
||||||
const receive_fd = @import("./exchange-fd.zig").receive_fd;
|
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_HEADER_SIZE = 4; // Size (4 bytes) then content.
|
||||||
pub const IPC_BASE_SIZE = 100000; // 100 KB, plenty enough space for messages
|
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_MAX_MESSAGE_SIZE = IPC_BASE_SIZE - IPC_HEADER_SIZE;
|
||||||
pub const IPC_VERSION = 1;
|
|
||||||
|
|
||||||
// Context of the whole networking state.
|
// Context of the whole networking state.
|
||||||
pub const Context = struct {
|
pub const Context = struct {
|
||||||
|
@ -66,8 +59,8 @@ pub const Context = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allow mkdir to create a directory with 0o770 permissions.
|
// Allow mkdir to create a directory with 0o770 permissions.
|
||||||
const previous_mask = umask(0o007);
|
const previous_mask = c.umask(0o007);
|
||||||
defer _ = umask(previous_mask);
|
defer _ = c.umask(previous_mask);
|
||||||
|
|
||||||
// Create the run directory, where all UNIX sockets will be.
|
// Create the run directory, where all UNIX sockets will be.
|
||||||
posix.mkdir(rundir, 0o0770) catch |err| switch (err) {
|
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 {
|
pub fn deinit(self: *Self) void {
|
||||||
|
@ -264,8 +262,8 @@ pub const Context = struct {
|
||||||
|
|
||||||
// Allow to create a unix socket with the right permissions.
|
// Allow to create a unix socket with the right permissions.
|
||||||
// Group should include write permissions.
|
// Group should include write permissions.
|
||||||
const previous_mask = umask(0o117);
|
const previous_mask = c.umask(0o117);
|
||||||
defer _ = umask(previous_mask);
|
defer _ = c.umask(previous_mask);
|
||||||
|
|
||||||
// Remove the old UNIX socket.
|
// Remove the old UNIX socket.
|
||||||
posix.unlink(path) catch |err| switch (err) {
|
posix.unlink(path) catch |err| switch (err) {
|
||||||
|
@ -297,12 +295,6 @@ pub const Context = struct {
|
||||||
_ = try m.write(writer); // returns paylen
|
_ = try m.write(writer); // returns paylen
|
||||||
|
|
||||||
_ = try stream.write(fbs.getWritten());
|
_ = 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 {
|
pub fn schedule(self: *Self, m: Message) !void {
|
||||||
|
|
|
@ -72,6 +72,17 @@ pub fn hexdump(stream: anytype, header: []const u8, buffer: []const u8) std.posi
|
||||||
try stream.writeAll("\n");
|
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;
|
const print = std.debug.print;
|
||||||
|
|
||||||
test "36-byte hexdump test" {
|
test "36-byte hexdump test" {
|
||||||
|
|
|
@ -5,6 +5,7 @@ const fmt = std.fmt;
|
||||||
|
|
||||||
const print_eq = @import("./util.zig").print_eq;
|
const print_eq = @import("./util.zig").print_eq;
|
||||||
|
|
||||||
|
const payload_header_length = 4;
|
||||||
pub const Messages = std.ArrayList(Message);
|
pub const Messages = std.ArrayList(Message);
|
||||||
|
|
||||||
pub const Message = struct {
|
pub const Message = struct {
|
||||||
|
@ -28,17 +29,17 @@ pub const Message = struct {
|
||||||
var reader = fbs.reader();
|
var reader = fbs.reader();
|
||||||
|
|
||||||
const msg_len = try reader.readInt(u32, .big);
|
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;
|
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);
|
return try Message.init(fd, allocator, msg_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(self: Self, writer: anytype) !usize {
|
pub fn write(self: Self, writer: anytype) !usize {
|
||||||
try writer.writeInt(u32, @as(u32, @truncate(self.payload.len)), .big);
|
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 {
|
pub fn format(self: Self, comptime _: []const u8, _: fmt.FormatOptions, out_stream: anytype) !void {
|
||||||
|
|
|
@ -40,10 +40,12 @@ pub const SwitchDB = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
db: std.AutoArrayHashMap(i32, ManagedConnection),
|
db: std.AutoArrayHashMap(i32, ManagedConnection),
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) Self {
|
pub fn init(allocator: Allocator) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.db = std.AutoArrayHashMap(i32, ManagedConnection).init(allocator),
|
.db = std.AutoArrayHashMap(i32, ManagedConnection).init(allocator),
|
||||||
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,9 +89,10 @@ pub const SwitchDB = struct {
|
||||||
},
|
},
|
||||||
CBEventType.NO_ERROR => {
|
CBEventType.NO_ERROR => {
|
||||||
// TODO: read message
|
// TODO: read message
|
||||||
// TODO: better allocator?
|
|
||||||
// TODO: better errors?
|
// 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 error.generic;
|
||||||
};
|
};
|
||||||
return message;
|
return message;
|
||||||
|
|
Loading…
Reference in New Issue