Tests are passing. Simpler makefile.
parent
1a161d1b14
commit
98eede6814
|
@ -1,24 +1,24 @@
|
||||||
all:
|
all:
|
||||||
|
|
||||||
ZIGBUSEOPTS ?= -OReleaseSmall
|
ZIGMAKEDOC = -femit-docs -fno-emit-bin
|
||||||
ZIGUSROPTS ?= -freference-trace
|
ZIGOPTIM ?= Debug
|
||||||
|
ZIGBUSEOPTS ?= -O$(ZIGOPTIM) -freference-trace
|
||||||
|
ZIGUSROPTS ?=
|
||||||
ZIGC ?= zig
|
ZIGC ?= zig
|
||||||
ZIGOPTS ?= $(ZIGBUSEOPTS) $(ZIGUSROPTS)
|
ZIGOPTS ?= $(ZIGBUSEOPTS) $(ZIGUSROPTS)
|
||||||
|
|
||||||
c: src/send-msg.zig
|
ipcd: src/ipcd.zig
|
||||||
$(ZIGC) build-exe $(ZIGOPTS) $^
|
$(ZIGC) build-exe $(ZIGOPTS) $^
|
||||||
|
|
||||||
s: src/receive-msg.zig
|
test-libipc: src/main.zig
|
||||||
$(ZIGC) build-exe $(ZIGOPTS) $^
|
|
||||||
|
|
||||||
m: src/main.zig
|
|
||||||
$(ZIGC) build-exe $(ZIGOPTS) $^
|
|
||||||
|
|
||||||
t: src/main.zig
|
|
||||||
$(ZIGC) test $(ZIGOPTS) $^
|
$(ZIGC) test $(ZIGOPTS) $^
|
||||||
|
|
||||||
d: src/main.zig
|
test-ipcd: src/ipcd.zig
|
||||||
$(ZIGC) build-exe $(ZIGOPTS) $^
|
|
||||||
|
|
||||||
o: $(SRC)
|
|
||||||
$(ZIGC) test $(ZIGOPTS) $^
|
$(ZIGC) test $(ZIGOPTS) $^
|
||||||
|
|
||||||
|
doc: src/ipcd.zig
|
||||||
|
$(ZIGC) build-exe $(ZIGOPTS) $(ZIGMAKEDOC) $^
|
||||||
|
|
||||||
|
|
||||||
|
# You can add your specific instructions there.
|
||||||
|
-include makefile.user
|
||||||
|
|
|
@ -39,7 +39,6 @@ pub const Connection = struct {
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
if (self.server) |*s| { s.deinit(); }
|
if (self.server) |*s| { s.deinit(); }
|
||||||
if (self.client) |*c| { c.deinit(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -370,7 +370,6 @@ pub const Context = struct {
|
||||||
c.stream.close();
|
c.stream.close();
|
||||||
}
|
}
|
||||||
var pollfd = self.pollfd.swapRemove(index);
|
var pollfd = self.pollfd.swapRemove(index);
|
||||||
print("client at index {} removed\n", .{index});
|
|
||||||
|
|
||||||
// Remove all its non-sent messages.
|
// Remove all its non-sent messages.
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
@ -380,7 +379,6 @@ pub const Context = struct {
|
||||||
|
|
||||||
if (self.tx.items[i].fd == pollfd.fd) {
|
if (self.tx.items[i].fd == pollfd.fd) {
|
||||||
var m = self.tx.swapRemove(i);
|
var m = self.tx.swapRemove(i);
|
||||||
print("Removing message targeted to client {}: {}\n", .{index, m});
|
|
||||||
m.deinit();
|
m.deinit();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +473,13 @@ test "Context - creation, display and memory check" {
|
||||||
var path = fbs.getWritten();
|
var path = fbs.getWritten();
|
||||||
|
|
||||||
// SERVER SIDE: creating a service.
|
// SERVER SIDE: creating a service.
|
||||||
var server = try c.server_init(path);
|
var server = c.server_init(path) catch |err| switch(err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
print ("\nError: cannot init server at {s}\n", .{path});
|
||||||
|
return err;
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
defer std.fs.cwd().deleteFile(path) catch {}; // Once done, remove file.
|
defer std.fs.cwd().deleteFile(path) catch {}; // Once done, remove file.
|
||||||
|
|
||||||
|
@ -549,7 +553,13 @@ const ConnectThenSendMessageThread = struct {
|
||||||
var path = fbs.getWritten();
|
var path = fbs.getWritten();
|
||||||
|
|
||||||
// SERVER SIDE: creating a service.
|
// SERVER SIDE: creating a service.
|
||||||
var server = try c.server_init(path);
|
var server = c.server_init(path) catch |err| switch(err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
print ("\nError: cannot init server at {s}\n", .{path});
|
||||||
|
return err;
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
defer std.fs.cwd().deleteFile(path) catch {}; // Once done, remove file.
|
defer std.fs.cwd().deleteFile(path) catch {}; // Once done, remove file.
|
||||||
|
|
||||||
|
@ -561,7 +571,7 @@ const ConnectThenSendMessageThread = struct {
|
||||||
defer client.stream.close();
|
defer client.stream.close();
|
||||||
var buf: [1000]u8 = undefined;
|
var buf: [1000]u8 = undefined;
|
||||||
const n = try client.stream.reader().read(&buf);
|
const n = try client.stream.reader().read(&buf);
|
||||||
var m = try Message.read(buf[0..n], allocator);
|
var m = try Message.read(8, buf[0..n], allocator); // 8 == random client's fd number
|
||||||
defer m.deinit();
|
defer m.deinit();
|
||||||
|
|
||||||
try testing.expectEqual(@as(usize, 12), m.payload.len);
|
try testing.expectEqual(@as(usize, 12), m.payload.len);
|
||||||
|
|
|
@ -91,7 +91,7 @@ test "Event - creation and display" {
|
||||||
var s = "hello!!";
|
var s = "hello!!";
|
||||||
var m = try Message.init(1, Message.Type.DATA, allocator, s); // fd type payload
|
var m = try Message.init(1, Message.Type.DATA, allocator, s); // fd type payload
|
||||||
defer m.deinit();
|
defer m.deinit();
|
||||||
var e = Event.init(Event.Type.CONNECTION, 5, 8, &m); // type index origin message
|
var e = Event.init(Event.Type.CONNECTION, 5, 8, m); // type index origin message
|
||||||
|
|
||||||
try print_eq("event.Event.Type.CONNECTION, origin: 8, index 5, message: [fd: 1, message.Message.Type.DATA, payload: [hello!!]]", e);
|
try print_eq("event.Event.Type.CONNECTION, origin: 8, index 5, message: [fd: 1, message.Message.Type.DATA, payload: [hello!!]]", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const hexdump = @import("./hexdump.zig");
|
||||||
|
const net = std.net;
|
||||||
|
const fmt = std.fmt;
|
||||||
|
|
||||||
|
const ipc = @import("./main.zig");
|
||||||
|
|
||||||
|
const print = std.debug.print;
|
||||||
|
const testing = std.testing;
|
||||||
|
const print_eq = @import("./util.zig").print_eq;
|
||||||
|
|
||||||
|
// TODO: file descriptors should have a specific type (but i32 is used in std.net...).
|
||||||
|
|
||||||
|
// TODO: path => std.XXX.YYY, not simple [] const u8
|
||||||
|
|
||||||
|
// TODO: both Connection and pollfd store file descriptors.
|
||||||
|
// Connection stores either Stream (server) or Address (client).
|
||||||
|
|
||||||
|
// TODO: API should completely obfuscate the inner structures.
|
||||||
|
// Only structures in this file should be necessary.
|
||||||
|
|
||||||
|
var should_quit: bool = false;
|
||||||
|
|
||||||
|
fn create_service() !void {
|
||||||
|
const config = .{.safety = true};
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(config){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
var ctx = try ipc.Context.init(allocator);
|
||||||
|
defer ctx.deinit(); // There. Can't leak. Isn't Zig wonderful?
|
||||||
|
|
||||||
|
const path = "/tmp/.TEST_USOCK";
|
||||||
|
|
||||||
|
// SERVER SIDE: creating a service.
|
||||||
|
_ = try ctx.server_init(path);
|
||||||
|
|
||||||
|
// TODO: signal handler, to quit when asked
|
||||||
|
|
||||||
|
var some_event: ipc.Event = undefined;
|
||||||
|
ctx.timer = 2000; // 1 second
|
||||||
|
while(true) {
|
||||||
|
some_event = try ctx.wait_event();
|
||||||
|
switch (some_event.t) {
|
||||||
|
.CONNECTION => {
|
||||||
|
print("New connection: {}!\n", .{some_event});
|
||||||
|
},
|
||||||
|
.TIMER => {
|
||||||
|
print("Timer!\n", .{});
|
||||||
|
},
|
||||||
|
.EXTERNAL => {
|
||||||
|
print("Message received from a non IPC socket.\n", .{});
|
||||||
|
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
.SWITCH => {
|
||||||
|
print("Message to send to a corresponding fd.\n", .{});
|
||||||
|
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
.DISCONNECTION => {
|
||||||
|
print("User disconnected.\n", .{});
|
||||||
|
},
|
||||||
|
.MESSAGE => {
|
||||||
|
print("New message. {}\n", .{some_event});
|
||||||
|
print("Let's echo, once\n", .{});
|
||||||
|
if (some_event.m) |m| {
|
||||||
|
try ctx.schedule(m);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.LOOKUP => {
|
||||||
|
print("Client asking for a service through ipcd.\n", .{});
|
||||||
|
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
.TX => {
|
||||||
|
print("Message sent.\n", .{});
|
||||||
|
},
|
||||||
|
.NOT_SET => {
|
||||||
|
print("Event type not set. Something is wrong, let's suicide.\n", .{});
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
.ERROR => {
|
||||||
|
print("A problem occured, event: {}, let's suicide\n", .{some_event});
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_quit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Server.accept returns a net.Connection (handle = fd, addr = net.Address).
|
||||||
|
// var client = try server.accept();
|
||||||
|
// var buf: [4096]u8 = undefined;
|
||||||
|
// const n = try ctx.read_ (client, &buf);
|
||||||
|
|
||||||
|
// print("new client: {}\n", .{client});
|
||||||
|
// print("{} bytes: {s}\n", .{n, buf});
|
||||||
|
print("End the create_service function\n", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() !u8 {
|
||||||
|
try create_service();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,32 +1,13 @@
|
||||||
const std = @import("std");
|
pub const CBEvent = @import("./callback.zig").CBEvent;
|
||||||
const hexdump = @import("./hexdump.zig");
|
pub const Connection = @import("./connection.zig").Connection;
|
||||||
const testing = std.testing;
|
pub const Message = @import("./message.zig").Message;
|
||||||
const net = std.net;
|
pub const Event = @import("./event.zig").Event;
|
||||||
const fmt = std.fmt;
|
pub const Switch = @import("./switch.zig").Switch;
|
||||||
|
|
||||||
// TODO: file descriptors should have a specific type (but i32 is used in std.net...).
|
pub const Messages = @import("./message.zig").Messages;
|
||||||
|
pub const Switches = @import("./switch.zig").Switches;
|
||||||
// TODO: path => std.XXX.YYY, not simple [] const u8
|
pub const Connections = @import("./connection.zig").Connections;
|
||||||
|
pub const Context = @import("./context.zig").Context;
|
||||||
// TODO: both Connection and pollfd store file descriptors.
|
|
||||||
// Connection stores either Stream (server) or Address (client).
|
|
||||||
|
|
||||||
// TODO: API should completely obfuscate the inner structures.
|
|
||||||
// Only structures in this file should be necessary.
|
|
||||||
|
|
||||||
const CBEvent = @import("./callback.zig").CBEvent;
|
|
||||||
const Connection = @import("./connection.zig").Connection;
|
|
||||||
const Message = @import("./message.zig").Message;
|
|
||||||
const Event = @import("./event.zig").Event;
|
|
||||||
const Switch = @import("./switch.zig").Switch;
|
|
||||||
const print_eq = @import("./util.zig").print_eq;
|
|
||||||
|
|
||||||
const print = std.debug.print;
|
|
||||||
|
|
||||||
const Messages = @import("./message.zig").Messages;
|
|
||||||
const Switches = @import("./switch.zig").Switches;
|
|
||||||
const Connections = @import("./connection.zig").Connections;
|
|
||||||
const Context = @import("./context.zig").Context;
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("./callback.zig");
|
_ = @import("./callback.zig");
|
||||||
|
@ -38,90 +19,3 @@ test {
|
||||||
_ = @import("./util.zig");
|
_ = @import("./util.zig");
|
||||||
}
|
}
|
||||||
|
|
||||||
var should_quit: bool = false;
|
|
||||||
|
|
||||||
fn create_service() !void {
|
|
||||||
const config = .{.safety = true};
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(config){};
|
|
||||||
defer _ = gpa.deinit();
|
|
||||||
const allocator = gpa.allocator();
|
|
||||||
|
|
||||||
var ctx = try Context.init(allocator);
|
|
||||||
defer ctx.deinit(); // There. Can't leak. Isn't Zig wonderful?
|
|
||||||
|
|
||||||
const path = "/tmp/.TEST_USOCK";
|
|
||||||
|
|
||||||
// SERVER SIDE: creating a service.
|
|
||||||
_ = try ctx.server_init(path);
|
|
||||||
|
|
||||||
// TODO: signal handler, to quit when asked
|
|
||||||
|
|
||||||
var some_event: Event = undefined;
|
|
||||||
ctx.timer = 2000; // 1 second
|
|
||||||
while(true) {
|
|
||||||
some_event = try ctx.wait_event();
|
|
||||||
switch (some_event.t) {
|
|
||||||
.CONNECTION => {
|
|
||||||
print("New connection: {}!\n", .{some_event});
|
|
||||||
},
|
|
||||||
.TIMER => {
|
|
||||||
print("Timer!\n", .{});
|
|
||||||
},
|
|
||||||
.EXTERNAL => {
|
|
||||||
print("Message received from a non IPC socket.\n", .{});
|
|
||||||
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
.SWITCH => {
|
|
||||||
print("Message to send to a corresponding fd.\n", .{});
|
|
||||||
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
.DISCONNECTION => {
|
|
||||||
print("User disconnected.\n", .{});
|
|
||||||
},
|
|
||||||
.MESSAGE => {
|
|
||||||
print("New message. {}\n", .{some_event});
|
|
||||||
print("Let's echo, once\n", .{});
|
|
||||||
if (some_event.m) |m| {
|
|
||||||
try ctx.schedule(m);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.LOOKUP => {
|
|
||||||
print("Client asking for a service through ipcd.\n", .{});
|
|
||||||
print("NOT IMPLEMENTED, YET. It's a suicide, then.\n", .{});
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
.TX => {
|
|
||||||
print("Message sent.\n", .{});
|
|
||||||
},
|
|
||||||
.NOT_SET => {
|
|
||||||
print("Event type not set. Something is wrong, let's suicide.\n", .{});
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
.ERROR => {
|
|
||||||
print("A problem occured, event: {}, let's suicide\n", .{some_event});
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_quit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Server.accept returns a net.Connection (handle = fd, addr = net.Address).
|
|
||||||
// var client = try server.accept();
|
|
||||||
// var buf: [4096]u8 = undefined;
|
|
||||||
// const n = try ctx.read_ (client, &buf);
|
|
||||||
|
|
||||||
// print("new client: {}\n", .{client});
|
|
||||||
// print("{} bytes: {s}\n", .{n, buf});
|
|
||||||
print("End the create_service function\n", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() !u8 {
|
|
||||||
try create_service();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -123,7 +123,8 @@ test "Message - read and write" {
|
||||||
var second_allocator = fba.allocator();
|
var second_allocator = fba.allocator();
|
||||||
|
|
||||||
// Read the buffer, similar to receiving a message on the network.
|
// Read the buffer, similar to receiving a message on the network.
|
||||||
var second_message = try Message.read(buffer[0..count], second_allocator);
|
// (8 == random client's fd number)
|
||||||
|
var second_message = try Message.read(8, buffer[0..count], second_allocator);
|
||||||
// var second_message = try Message.read(fbs.getWritten(), second_allocator);
|
// var second_message = try Message.read(fbs.getWritten(), second_allocator);
|
||||||
defer second_message.deinit();
|
defer second_message.deinit();
|
||||||
|
|
||||||
|
|
Reference in New Issue