Compare commits
2 Commits
ec0f736cad
...
685d8b574b
Author | SHA1 | Date | |
---|---|---|---|
685d8b574b | |||
7e2a3b04fa |
|
@ -20,12 +20,14 @@ dir_nfds_t: usize = 0,
|
||||||
dir_wds: [MAX_FDS]Wd = [_]Wd{.{}} ** MAX_FDS,
|
dir_wds: [MAX_FDS]Wd = [_]Wd{.{}} ** MAX_FDS,
|
||||||
control_socket: ?std.os.socket_t = null,
|
control_socket: ?std.os.socket_t = null,
|
||||||
watch_started: bool = false,
|
watch_started: bool = false,
|
||||||
|
sock_name: [:0]const u8,
|
||||||
|
|
||||||
pub fn init(file_changed: *const fn (usize) void) Self {
|
pub fn init(file_changed: *const fn (usize) void) Self {
|
||||||
if (builtin.os.tag != .linux)
|
if (builtin.os.tag != .linux)
|
||||||
@compileError("Unsupported OS");
|
@compileError("Unsupported OS");
|
||||||
return .{
|
return .{
|
||||||
.fileChanged = file_changed,
|
.fileChanged = file_changed,
|
||||||
|
.sock_name = sockName(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,12 +52,15 @@ pub fn deinit(self: *Self) void {
|
||||||
std.os.close(fd);
|
std.os.close(fd);
|
||||||
}
|
}
|
||||||
const cwd = std.fs.cwd();
|
const cwd = std.fs.cwd();
|
||||||
cwd.deleteFileZ(SOCK_NAME) catch |e|
|
cwd.deleteFileZ(self.sock_name) catch |e|
|
||||||
log.err("error removing socket file " ++ SOCK_NAME ++ ": {any}", .{e});
|
log.err("error removing socket file {s}: {any}", .{ self.sock_name, e });
|
||||||
}
|
}
|
||||||
|
|
||||||
const SOCK_NAME = "S.watch-control";
|
const SOCK_NAME = "S.watch-control";
|
||||||
|
var buf = [_]u8{0} ** (SOCK_NAME.len + "-9223372036854775807 ".len);
|
||||||
|
fn sockName() [:0]const u8 {
|
||||||
|
return std.fmt.bufPrintZ(buf[0..], "{s}-{d}", .{ SOCK_NAME, std.time.timestamp() }) catch unreachable; // buffer designed for Max(i64) with sock name and a trailing \0
|
||||||
|
}
|
||||||
/// starts the file watch. This function will not return, so it is best
|
/// starts the file watch. This function will not return, so it is best
|
||||||
/// to put this function in its own thread:
|
/// to put this function in its own thread:
|
||||||
///
|
///
|
||||||
|
@ -66,7 +71,7 @@ const SOCK_NAME = "S.watch-control";
|
||||||
/// is intended later
|
/// is intended later
|
||||||
pub fn startWatch(self: *Self) void {
|
pub fn startWatch(self: *Self) void {
|
||||||
if (self.control_socket == null)
|
if (self.control_socket == null)
|
||||||
self.addControlSocket(SOCK_NAME) catch @panic("could not add control socket");
|
self.addControlSocket(self.sock_name) catch @panic("could not add control socket");
|
||||||
std.debug.assert(self.control_socket != null);
|
std.debug.assert(self.control_socket != null);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -103,7 +108,7 @@ pub fn startWatch(self: *Self) void {
|
||||||
|
|
||||||
// self.control_socket_accepted_fd = self.control_socket_accepted_fd orelse acceptSocket(self.control_socket.?);
|
// self.control_socket_accepted_fd = self.control_socket_accepted_fd orelse acceptSocket(self.control_socket.?);
|
||||||
// const fd = self.control_socket_accepted_fd.?; // let's save some typing
|
// const fd = self.control_socket_accepted_fd.?; // let's save some typing
|
||||||
const fd = acceptSocket(self.control_socket.?);
|
const fd = acceptSocket(self.sock_name, self.control_socket.?);
|
||||||
defer std.os.close(fd);
|
defer std.os.close(fd);
|
||||||
|
|
||||||
var readcount = std.os.recv(fd, &control_buf, 0) catch unreachable;
|
var readcount = std.os.recv(fd, &control_buf, 0) catch unreachable;
|
||||||
|
@ -157,8 +162,8 @@ pub fn startWatch(self: *Self) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn acceptSocket(socket: std.os.socket_t) std.os.socket_t {
|
fn acceptSocket(name: [:0]const u8, socket: std.os.socket_t) std.os.socket_t {
|
||||||
var sockaddr = std.net.Address.initUnix(SOCK_NAME) catch @panic("could not get sockaddr");
|
var sockaddr = std.net.Address.initUnix(name) catch @panic("could not get sockaddr");
|
||||||
var sockaddr_len: std.os.socklen_t = sockaddr.getOsSockLen();
|
var sockaddr_len: std.os.socklen_t = sockaddr.getOsSockLen();
|
||||||
log.debug("tid={d} accepting on socket fd {d}", .{ std.Thread.getCurrentId(), socket });
|
log.debug("tid={d} accepting on socket fd {d}", .{ std.Thread.getCurrentId(), socket });
|
||||||
return std.os.accept(
|
return std.os.accept(
|
||||||
|
@ -322,7 +327,7 @@ fn sendControl(self: Self, control: u8) !void {
|
||||||
// log.debug("request to send control 0x{x}", .{control});
|
// log.debug("request to send control 0x{x}", .{control});
|
||||||
if (self.control_socket == null) return; // nothing to do
|
if (self.control_socket == null) return; // nothing to do
|
||||||
// log.debug("tid={d} opening stream", .{std.Thread.getCurrentId()});
|
// log.debug("tid={d} opening stream", .{std.Thread.getCurrentId()});
|
||||||
var stream = try std.net.connectUnixSocket(SOCK_NAME);
|
var stream = try std.net.connectUnixSocket(self.sock_name);
|
||||||
defer stream.close();
|
defer stream.close();
|
||||||
log.debug("tid={d} sending control 0x{x} on socket fd={d}", .{ std.Thread.getCurrentId(), control, stream.handle });
|
log.debug("tid={d} sending control 0x{x} on socket fd={d}", .{ std.Thread.getCurrentId(), control, stream.handle });
|
||||||
try stream.writer().writeByte(control);
|
try stream.writer().writeByte(control);
|
||||||
|
@ -373,7 +378,7 @@ fn addControlSocket(self: *Self, path: [:0]const u8) !void {
|
||||||
|
|
||||||
const sockaddr = try std.net.Address.initUnix(path);
|
const sockaddr = try std.net.Address.initUnix(path);
|
||||||
|
|
||||||
// TODO: If this bind fails with EADDRINUSE we can probably delete the existing file
|
log.debug("binding to path: {s}", .{path});
|
||||||
try std.os.bind(sock, &sockaddr.any, sockaddr.getOsSockLen());
|
try std.os.bind(sock, &sockaddr.any, sockaddr.getOsSockLen());
|
||||||
try std.os.listen(sock, 10);
|
try std.os.listen(sock, 10);
|
||||||
self.control_socket = sock;
|
self.control_socket = sock;
|
||||||
|
|
|
@ -25,7 +25,7 @@ const requestDeinitFn = *const fn () void;
|
||||||
|
|
||||||
const timeout = 250;
|
const timeout = 250;
|
||||||
|
|
||||||
var watcher = Watch.init(executorChanged);
|
var watcher: Watch = undefined;
|
||||||
var watcher_thread: ?std.Thread = null;
|
var watcher_thread: ?std.Thread = null;
|
||||||
|
|
||||||
// Timer used by processRequest to provide ttfb/ttlb data in output
|
// Timer used by processRequest to provide ttfb/ttlb data in output
|
||||||
|
@ -405,6 +405,7 @@ fn childMain(allocator: std.mem.Allocator) !void {
|
||||||
defer allocator.free(executors);
|
defer allocator.free(executors);
|
||||||
defer parsed_config.deinit();
|
defer parsed_config.deinit();
|
||||||
|
|
||||||
|
watcher = Watch.init(executorChanged);
|
||||||
watcher_thread = try std.Thread.spawn(.{}, Watch.startWatch, .{&watcher});
|
watcher_thread = try std.Thread.spawn(.{}, Watch.startWatch, .{&watcher});
|
||||||
|
|
||||||
var server = std.http.Server.init(allocator, .{ .reuse_address = true });
|
var server = std.http.Server.init(allocator, .{ .reuse_address = true });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user