diff --git a/zig-impl/src/bindings.zig b/zig-impl/src/bindings.zig index 730223d..41805dd 100644 --- a/zig-impl/src/bindings.zig +++ b/zig-impl/src/bindings.zig @@ -31,7 +31,6 @@ export fn ipc_context_deinit (ctx: *Context) callconv(.C) void { } export fn ipc_write (ctx: *Context, servicefd: i32, mcontent: [*]const u8, mlen: u32) i32 { - // TODO: better default length. var buffer: [100000]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buffer); @@ -53,10 +52,33 @@ export fn ipc_read_fd (ctx: *Context, fd: i32, buffer: [*]u8, buflen: *usize) i3 return 0; } -// pub fn schedule (ctx: *Context, m: Message) !void +export fn ipc_schedule (ctx: *Context, servicefd: i32, mcontent: [*]const u8, mlen: u32) i32 { + var message = Message.init(servicefd, ctx.allocator, mcontent[0..mlen]) catch return -1; + ctx.schedule(message) catch return -2; + return 0; +} + +export fn ipc_wait_event(ctx: *Context, t: *u8, index: *usize, originfd: *i32, buffer: [*]u8, buflen: *usize) i32 { + var event = ctx.wait_event() catch return -1; + t.* = @enumToInt(event.t); + index.* = event.index; + originfd.* = event.origin; + + if (event.m) |m| { + var fbs = std.io.fixedBufferStream(buffer[0..buflen.*]); + var writer = fbs.writer(); + _ = writer.write(m.payload) catch return -4; + buflen.* = m.payload.len; + } + else { + buflen.* = 0; + } + + return 0; +} + // pub fn read (ctx: *Context, index: usize) !?Message // -// pub fn wait_event(ctx: *Context) !Event // // pub fn close_fd(ctx: *Context, fd: i32) !void // pub fn close(ctx: *Context, index: usize) !void diff --git a/zig-impl/test-bindings/pong.c b/zig-impl/test-bindings/pong.c index 0cb56b6..306dd79 100644 --- a/zig-impl/test-bindings/pong.c +++ b/zig-impl/test-bindings/pong.c @@ -4,7 +4,25 @@ #define SERVICE "pong" #define SERVICE_LEN 4 +enum event_types { + ERROR = 0 // A problem occured. + , EXTERNAL = 1 // Message received from a non IPC socket. + , SWITCH_RX = 2 // Message received from a switched FD. + , SWITCH_TX = 3 // Message sent to a switched fd. + , CONNECTION = 4 // New user. + , DISCONNECTION = 5 // User disconnected. + , MESSAGE = 6 // New message. + , TIMER = 7 // Timeout in the poll(2) function. + , TX = 8 // Message sent. +}; + + int main(void) { + direct_write_then_read(); + wait_event(); +} + +int direct_write_then_read(void) { int ret = 0; int servicefd = 0; @@ -17,8 +35,6 @@ int main(void) { return 1; } - printf ("Context initiated.\n"); - printf ("Connect to a 'pong' service.\n"); ret = ipc_connect_service (ctx, &servicefd, SERVICE, SERVICE_LEN); @@ -37,24 +53,13 @@ int main(void) { char message[10000]; unsigned int size = 10000; -#if 1 + ret = ipc_read_fd (ctx, servicefd, message, &size); if (ret != 0) { printf ("Cannot read from the service fd: %d.\n", ret); return 1; } -#else - // TODO: loop over ipc_wait - int event_type, index, originfd = 0; - printf ("Wait for a response.\n", ret); - ret = ipc_wait (&event_type, &index, &originfd, &size, message); - - if (ret != 0) { - printf ("Error while waiting for an event.\n"); - return 1; - } -#endif if (size == 0) { printf ("No message returned.\n"); @@ -72,3 +77,107 @@ int main(void) { printf ("Context freed.\n"); return 0; } + +int wait_event(void) { + int ret = 0; + int servicefd = 0; + char message[10000]; + unsigned int size = 10000; + char event_type; + unsigned int index = 0; + int originfd = 0; + void *ctx = NULL; + + printf ("Init context.\n"); + ret = ipc_context_init (&ctx); + + if (ret != 0) { + printf ("Cannot init context.\n"); + return 1; + } + + printf ("Connect to a 'pong' service.\n"); + ret = ipc_connect_service (ctx, &servicefd, SERVICE, SERVICE_LEN); + + if (ret != 0) { + printf ("Cannot connect to a service.\n"); + return 1; + } + + printf ("Let's schedule a message.\n"); + ret = ipc_schedule (ctx, servicefd, "hello, plz bounce me", 21); + + if (ret != 0) { + printf ("Cannot schedule a message.\n"); + return 1; + } + + printf ("Let's loop over events.\n"); + char should_continue = 1; + unsigned int count = 0; + while(should_continue) { + size = 10000; + ret = ipc_wait_event (ctx, &event_type, &index, &originfd, message, &size); + if (ret != 0) { + printf ("Error while waiting for an event.\n"); + return 1; + } + + printf ("EVENT %u\t", count++); + + switch ((enum event_types) event_type) { + case ERROR: { + printf ("Error.\n"); + return 1; + } + case EXTERNAL: { + printf ("External (shouldn't happen).\n"); + return 1; + } + case SWITCH_RX: { + printf ("Switch RX (shouldn't happen).\n"); + return 1; + } + case SWITCH_TX: { + printf ("Switch TX (shouldn't happen).\n"); + return 1; + } + case CONNECTION: { + printf ("Connection (shouldn't happen).\n"); + return 1; + } + case DISCONNECTION: { + printf ("Disconnection (shouldn't happen).\n"); + return 1; + } + case TIMER: { + printf ("TIMER.\n"); + break; + } + case TX: { + printf ("A message has been sent.\n"); + break; + } + case MESSAGE: { + if (size == 0) { + printf ("No message returned.\n"); + return 1; + } + + message[size] = '\0'; + printf ("Response: %s.\n", message); + // We received the response, quitting. + should_continue = 0; + break; + } + } + } + + printf ("Deinit context\n"); + ipc_context_deinit (ctx); + + free(ctx); + + printf ("Context freed.\n"); + return 0; +}