From ec787d74969ec50cb247c3060c133cbefa97b45e Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Sat, 7 Jan 2023 19:04:05 +0100 Subject: [PATCH] Switch: fn draft for read/write switched ipc messages. --- zig-impl/src/context.zig | 6 +-- zig-impl/src/switch.zig | 79 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/zig-impl/src/context.zig b/zig-impl/src/context.zig index 336aea3..1e24b42 100644 --- a/zig-impl/src/context.zig +++ b/zig-impl/src/context.zig @@ -308,7 +308,7 @@ pub const Context = struct { return try Message.read(fd, buffer[0..], self.allocator); } - // Wait an event. + // Wait for an event. pub fn wait_event(self: *Self) !Event { var current_event: Event = Event.init(Event.Type.ERROR, 0, 0, null); var wait_duration: i32 = -1; // -1 == unlimited @@ -370,7 +370,7 @@ pub const Context = struct { } // SWITCHED = send message to the right dest (or drop the switch) else if (self.connections.items[i].t == .SWITCHED) { - // TODO: send message to SWITCH dest + // TODO: read message from fd.fd + schedule read message return Event.init(Event.Type.SWITCH, i, fd.fd, null); } // EXTERNAL = user handles IO @@ -403,7 +403,7 @@ pub const Context = struct { // SWITCHED = write message for its switch buddy (callbacks) if (self.connections.items[i].t == .SWITCHED) { - // TODO: handle_writing_switched_message + // TODO: write message return Event.init(Event.Type.SWITCH, i, fd.fd, null); } else { diff --git a/zig-impl/src/switch.zig b/zig-impl/src/switch.zig index cafeabf..59dd0bf 100644 --- a/zig-impl/src/switch.zig +++ b/zig-impl/src/switch.zig @@ -18,19 +18,69 @@ const Event = ipc.Event; pub const Switches = struct { const Self = @This(); - // db: std.HashList(i32, ManagedConnection), + db: std.AutoArrayHashMap(i32, ManagedConnection), - pub fn init (_: Allocator) !Self { + pub fn init (allocator: Allocator) Self { return Self { - // .db = try std.HashList(i32, ManagedConnection).init(allocator), + .db = std.AutoArrayHashMap(i32, ManagedConnection).init(allocator), }; } - pub fn deinit (_: *Self) void { + pub fn deinit (self: *Self) void { + self.deinit(); } + // read message from switched fd + pub fn read (self: *Self, fd: i32) !?Message + { + // If the socket is associated to another one for ipcd: + // read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch. - // pub fn read(fd: i32) + var managedconnection = self.db.get(fd); + var message: Message = undefined; + + var r: CBEventType = managedconnection.in(fd, &message); + + switch (r) { + // The message should be ignored (protocol specific). + .IGNORE => { return null; }, + // No error. A message was generated. + .NO_ERROR => { + message.fd = managedconnection.dest; + return message; + }, + .FD_CLOSING => { return error.closeFD; }, + // Generic error, or the message was read but with errors. + .FD_ERROR + .PARSING_ERROR => { + return error.generic; + }, + }; + } + + // fd_switching_write enables to write a message to a switched fd. + pub fn write (message: Message) !void { + + var managedconnection = self.db.get(message.fd); + var r = managedconnection.out(managedconnection.dest, message); + + switch (r) { + // The message should be ignored (protocol specific). + // No error. A message was generated. + .NO_ERROR => { + return; + }, + .FD_CLOSING => { return error.closeFD; }, + // Generic error, or the message was read but with errors. + .IGNORE + .FD_ERROR + .PARSING_ERROR => { + return error.generic; + }, + }; + + unreachable; + } }; pub const ManagedConnection = struct { @@ -50,6 +100,19 @@ pub const ManagedConnection = struct { // } }; +test "creation and display" { + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var switchdb = Switches.init(allocator); + defer switchdb.deinit(); + + switchdb.db.put(5, ManagedConnection {.dest = 6}); + switchdb.db.put(6, ManagedConnection {.dest = 5}); +} + // For IO callbacks (switching). // pub const Type = enum { // NO_ERROR, // No error. A message was generated. @@ -60,7 +123,7 @@ pub const ManagedConnection = struct { // }; fn default_in (origin: i32, m: *Message) CBEventType { - print ("receiving a message originated by {}\n", .{origin}); + print ("receiving a message originated from {}\n", .{origin}); var buffer: [2000000]u8 = undefined; // TODO: FIXME?? var packet_size: usize = undefined; @@ -73,15 +136,15 @@ fn default_in (origin: i32, m: *Message) CBEventType { return CBEventType.FD_CLOSING; } + // TODO: handle memory errors. m.* = Message.read(origin, buffer[0..], std.heap.c_allocator) catch return CBEventType.FD_ERROR; - //** There is a message, send it to the corresponding fd **/ return CBEventType.NO_ERROR; } fn default_out (origin: i32, m: *Message) CBEventType { - print ("sending a message originated by {}\n", .{origin}); + print ("sending a message originated from {}\n", .{origin}); // Message contains the fd, no need to search for // the right structure to copy, let's just recreate // a Stream from the fd.