pong and pongd working (with C bindings)
This commit is contained in:
parent
670d0ac9f3
commit
4450500876
3 changed files with 124 additions and 10 deletions
26
build.zig
26
build.zig
|
|
@ -70,7 +70,7 @@ pub fn build(b: *std.Build) void {
|
||||||
dynamic_lib.root_module.link_libc = true;
|
dynamic_lib.root_module.link_libc = true;
|
||||||
b.installArtifact(dynamic_lib);
|
b.installArtifact(dynamic_lib);
|
||||||
|
|
||||||
// pong service using the c client.
|
// pong client using the c client.
|
||||||
const pong_with_c_bindings = b.addExecutable(.{
|
const pong_with_c_bindings = b.addExecutable(.{
|
||||||
.name = "pong-with-c-bindings", // name of the executable
|
.name = "pong-with-c-bindings", // name of the executable
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
|
|
@ -96,12 +96,26 @@ pub fn build(b: *std.Build) void {
|
||||||
// Statically link the executable to the library.
|
// Statically link the executable to the library.
|
||||||
pong_with_c_bindings.linkLibrary(static_lib);
|
pong_with_c_bindings.linkLibrary(static_lib);
|
||||||
|
|
||||||
|
// pong service using the c client.
|
||||||
|
const pongd_with_c_bindings = b.addExecutable(.{
|
||||||
|
.name = "pongd-with-c-bindings", // name of the executable
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/examples/pongd-with-c-bindings.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
|
||||||
|
// Again, no need for external modules to import.
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
b.installArtifact(pongd_with_c_bindings);
|
||||||
|
pongd_with_c_bindings.linkLibrary(static_lib);
|
||||||
|
|
||||||
// This creates a top level step. Top level steps have a name and can be
|
// This creates a top level step. Top level steps have a name and can be
|
||||||
// invoked by name when running `zig build` (e.g. `zig build run`).
|
// invoked by name when running `zig build` (e.g. `zig build run`).
|
||||||
// This will evaluate the `run` step rather than the default step.
|
// This will evaluate the `run` step rather than the default step.
|
||||||
// For a top level step to actually do something, it must depend on other
|
// For a top level step to actually do something, it must depend on other
|
||||||
// steps (e.g. a Run step, as we will see in a moment).
|
// steps (e.g. a Run step, as we will see in a moment).
|
||||||
const run_step = b.step("run-pong", "Run the pong client");
|
const run_pong_with_c_bindings_step = b.step("run-pong", "Run the pong client");
|
||||||
|
|
||||||
// This creates a RunArtifact step in the build graph. A RunArtifact step
|
// This creates a RunArtifact step in the build graph. A RunArtifact step
|
||||||
// invokes an executable compiled by Zig. Steps will only be executed by the
|
// invokes an executable compiled by Zig. Steps will only be executed by the
|
||||||
|
|
@ -109,17 +123,17 @@ pub fn build(b: *std.Build) void {
|
||||||
// or if another step depends on it, so it's up to you to define when and
|
// or if another step depends on it, so it's up to you to define when and
|
||||||
// how this Run step will be executed. In our case we want to run it when
|
// how this Run step will be executed. In our case we want to run it when
|
||||||
// the user runs `zig build run`, so we create a dependency link.
|
// the user runs `zig build run`, so we create a dependency link.
|
||||||
const run_cmd = b.addRunArtifact(pong_with_c_bindings);
|
const run_pong_with_c_bindings_cmd = b.addRunArtifact(pong_with_c_bindings);
|
||||||
run_step.dependOn(&run_cmd.step);
|
run_pong_with_c_bindings_step.dependOn(&run_pong_with_c_bindings_cmd.step);
|
||||||
|
|
||||||
// By making the run step depend on the default step, it will be run from the
|
// By making the run step depend on the default step, it will be run from the
|
||||||
// installation directory rather than directly from within the cache directory.
|
// installation directory rather than directly from within the cache directory.
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
run_pong_with_c_bindings_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
// This allows the user to pass arguments to the application in the build
|
// This allows the user to pass arguments to the application in the build
|
||||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||||
if (b.args) |args| {
|
if (b.args) |args| {
|
||||||
run_cmd.addArgs(args);
|
run_pong_with_c_bindings_cmd.addArgs(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an executable that will run `test` blocks from the provided module.
|
// Creates an executable that will run `test` blocks from the provided module.
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ pub fn main() !u8 {
|
||||||
libipc.ipc_context_timer (ctx, 1000);
|
libipc.ipc_context_timer (ctx, 1000);
|
||||||
|
|
||||||
var should_continue : bool = true;
|
var should_continue : bool = true;
|
||||||
var event_count : u32 = 0;
|
// var event_count : u32 = 0;
|
||||||
|
|
||||||
std.debug.print("Let's loop over events.\n", .{});
|
std.debug.print("Let's loop over events.\n", .{});
|
||||||
while(should_continue) {
|
while(should_continue) {
|
||||||
|
|
@ -66,8 +66,8 @@ pub fn main() !u8 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_count += 1;
|
// event_count += 1;
|
||||||
std.debug.print("EVENT n°{d} type {d}\t", .{ event_count, event_type });
|
// std.debug.print("EVENT n°{d} type {d}\t", .{ event_count, event_type });
|
||||||
|
|
||||||
switch (event_type) {
|
switch (event_type) {
|
||||||
libipc.ERROR => { std.debug.print("Error.", .{}); return 1; },
|
libipc.ERROR => { std.debug.print("Error.", .{}); return 1; },
|
||||||
|
|
@ -84,7 +84,7 @@ pub fn main() !u8 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
buffer[size] = 0;
|
buffer[size] = 0;
|
||||||
std.debug.print("Response (size {d}): {s}.\n", .{ size, buffer });
|
std.debug.print("Response (size {d}): {s}.\n", .{ size, buffer[0..size] });
|
||||||
// We received the response, quitting.
|
// We received the response, quitting.
|
||||||
should_continue = false;
|
should_continue = false;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
100
src/examples/pongd-with-c-bindings.zig
Normal file
100
src/examples/pongd-with-c-bindings.zig
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Example of a `pong` service using the C bindings.
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// Only bindings are available.
|
||||||
|
const libipc = @cImport({
|
||||||
|
@cInclude("../../../libipc.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
const SERVICE = "pong";
|
||||||
|
const SERVICE_LEN = 4;
|
||||||
|
const MAX_MSG_SIZE = 10000;
|
||||||
|
|
||||||
|
pub fn main() !u8 {
|
||||||
|
var ctx : *anyopaque = undefined;
|
||||||
|
var ret : c_int = 0;
|
||||||
|
var servicefd : c_int = undefined;
|
||||||
|
var buffer : [MAX_MSG_SIZE]u8 = undefined;
|
||||||
|
var size : usize = MAX_MSG_SIZE;
|
||||||
|
var event_type : u8 = undefined;
|
||||||
|
var index : usize = 0;
|
||||||
|
var originfd : c_int = undefined;
|
||||||
|
|
||||||
|
std.debug.print("Init context.\n", .{});
|
||||||
|
ret = libipc.ipc_context_init (@ptrCast(&ctx));
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
std.debug.print("Cannot init context.\n", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
std.debug.print("Deinit context.\n", .{});
|
||||||
|
libipc.ipc_context_deinit (@ptrCast(&ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print ("Create the 'pong' service.\n", .{});
|
||||||
|
ret = libipc.ipc_service_init (ctx, &servicefd, SERVICE, SERVICE_LEN);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
std.debug.print("Cannot create the service.\n", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print ("Listening to the standard input (press enter to quit).\n", .{});
|
||||||
|
ret = libipc.ipc_add_external (ctx, 0);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
std.debug.print ("Cannot listen to standard input.", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print("Set the timer to two seconds.\n", .{});
|
||||||
|
libipc.ipc_context_timer (ctx, 2000);
|
||||||
|
|
||||||
|
var event_count : u32 = 0;
|
||||||
|
|
||||||
|
std.debug.print("Let's loop over events.\n", .{});
|
||||||
|
while(true) {
|
||||||
|
size = MAX_MSG_SIZE;
|
||||||
|
var newfd : c_int = undefined;
|
||||||
|
const pbuffer : [*c]u8 = &buffer;
|
||||||
|
ret = libipc.ipc_wait_event (ctx, &event_type, &index, &originfd, &newfd, pbuffer, &size);
|
||||||
|
if (ret != 0) {
|
||||||
|
std.debug.print("Error while waiting for an event.", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_count += 1;
|
||||||
|
|
||||||
|
switch (event_type) {
|
||||||
|
libipc.ERROR => { std.debug.print("Error.", .{}); return 1; },
|
||||||
|
libipc.EXTERNAL => { std.debug.print("Quitting.\n", .{}); return 0; },
|
||||||
|
libipc.SWITCH_RX => { std.debug.print("Switch RX (shouldn't happen).", .{}); return 1; },
|
||||||
|
libipc.SWITCH_TX => { std.debug.print("Switch TX (shouldn't happen).", .{}); return 1; },
|
||||||
|
libipc.CONNECTION => { std.debug.print("Connection (fd {d}).\n", .{newfd}); },
|
||||||
|
libipc.DISCONNECTION => { std.debug.print("Disconnection (fd {d}).\n", .{originfd}); },
|
||||||
|
libipc.TIMER => { std.debug.print("\rTIMER ({d}).\r", .{event_count}); },
|
||||||
|
libipc.MESSAGE_TX => { std.debug.print("A message has been sent.\n", .{}); },
|
||||||
|
libipc.MESSAGE_RX => {
|
||||||
|
if (size == 0) {
|
||||||
|
std.debug.print("No message returned.\n", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
buffer[size] = 0;
|
||||||
|
std.debug.print("Message from {d} (size {d}): {s}.\n", .{ originfd, size, buffer[0..size] });
|
||||||
|
|
||||||
|
std.debug.print ("Schedule a message for {d}.\n", .{originfd});
|
||||||
|
ret = libipc.ipc_schedule (ctx, originfd, pbuffer, size);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
std.debug.print("Cannot schedule a message.\n", .{});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => { std.debug.print("Unknown IPC message type.\n", .{}); return 1; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue