1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
const std = @import("std");
const Allocator = std.mem.Allocator;
const DebugAllocator = std.heap.DebugAllocator;
const Sigaction = std.posix.Sigaction;
const Io = std.Io;
const Threaded = Io.Threaded;
const builtin = @import("builtin");
const zits = @import("zits");
const Message = zits.Server.message.Message;
const ServerInfo = Message.ServerInfo;
const Server = zits.Server;
const safe_build = builtin.mode == .Debug or builtin.mode == .ReleaseSafe;
var exit_lock: std.Io.Mutex = .init;
var io: Io = undefined;
fn handleSigInt(sig: std.os.linux.SIG) callconv(.c) void {
_ = sig;
exit_lock.unlock(io);
}
pub fn main(outer_alloc: Allocator, server_config: ServerInfo) !void {
{
var dba: DebugAllocator(.{}) = .init;
dba.backing_allocator = outer_alloc;
defer _ = dba.deinit();
const alloc = if (safe_build) dba.allocator() else outer_alloc;
var threaded: Threaded = .init(alloc, .{});
defer threaded.deinit();
io = threaded.io();
try exit_lock.lock(io);
// Configure the signal action
const act = Sigaction{
.handler = .{ .handler = handleSigInt },
.mask = std.posix.sigemptyset(),
.flags = 0,
};
// Register the handler for SIGINT (Ctrl+C)
std.posix.sigaction(std.posix.SIG.INT, &act, null);
var server: Server = .{
.info = server_config,
};
defer server.deinit(io, alloc);
var server_task = try io.concurrent(Server.start, .{ &server, io, alloc });
defer server_task.cancel(io) catch {};
// Block until Ctrl+C
try exit_lock.lock(io);
std.debug.print("\n", .{});
std.log.info("Shutting down...", .{});
server_task.cancel(io) catch {};
}
std.log.info("Goodbye", .{});
}
|