summaryrefslogtreecommitdiff
path: root/src/subcommand/server.zig
blob: 54258a97331c0633db294178daa22be1ce374c10 (plain) (blame)
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.parse.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", .{});
}