mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
fully integrate libuv, no crash on close
This commit is contained in:
19
src/App.zig
19
src/App.zig
@ -57,15 +57,14 @@ pub fn run(self: App) !void {
|
|||||||
}).callback);
|
}).callback);
|
||||||
defer embed.deinit(self.alloc);
|
defer embed.deinit(self.alloc);
|
||||||
try embed.start();
|
try embed.start();
|
||||||
errdefer embed.stop() catch unreachable;
|
errdefer embed.stop();
|
||||||
|
|
||||||
// We need at least one handle in the event loop at all times
|
// We need at least one handle in the event loop at all times so
|
||||||
|
// that the loop doesn't spin 100% CPU.
|
||||||
var timer = try libuv.Timer.init(self.alloc, self.loop);
|
var timer = try libuv.Timer.init(self.alloc, self.loop);
|
||||||
defer timer.deinit(self.alloc);
|
defer timer.deinit(self.alloc);
|
||||||
try timer.start((struct {
|
try timer.start((struct {
|
||||||
fn callback(_: libuv.Timer) void {
|
fn callback(_: libuv.Timer) void {}
|
||||||
log.info("timer tick", .{});
|
|
||||||
}
|
|
||||||
}).callback, 5000, 5000);
|
}).callback, 5000, 5000);
|
||||||
|
|
||||||
while (!self.window.shouldClose()) {
|
while (!self.window.shouldClose()) {
|
||||||
@ -79,5 +78,13 @@ pub fn run(self: App) !void {
|
|||||||
try embed.loopRun();
|
try embed.loopRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
try embed.stop();
|
// CLose our timer so that we can cleanly close the loop.
|
||||||
|
timer.close(null);
|
||||||
|
_ = try self.loop.run(.default);
|
||||||
|
|
||||||
|
// Notify the embedder to stop. We purposely do NOT wait for `join`
|
||||||
|
// here because handles with long timeouts may cause this to take a long
|
||||||
|
// time. We're exiting the app anyways if we're here so we let the OS
|
||||||
|
// clean up the threads.
|
||||||
|
embed.stop();
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ pub fn init(alloc: Allocator, loop: Loop, callback: fn () void) !Embed {
|
|||||||
/// Deinit the embed struct. This will not automatically terminate
|
/// Deinit the embed struct. This will not automatically terminate
|
||||||
/// the embed thread. You must call stop manually.
|
/// the embed thread. You must call stop manually.
|
||||||
pub fn deinit(self: *Embed, alloc: Allocator) void {
|
pub fn deinit(self: *Embed, alloc: Allocator) void {
|
||||||
std.debug.assert(self.thread == null);
|
|
||||||
self.sem.deinit(alloc);
|
self.sem.deinit(alloc);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
@ -48,19 +47,23 @@ pub fn start(self: *Embed) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stop stops the embed thread and blocks until the thread joins.
|
/// Stop stops the embed thread and blocks until the thread joins.
|
||||||
pub fn stop(self: *Embed) !void {
|
pub fn stop(self: *Embed) void {
|
||||||
var thread = self.thread orelse return;
|
if (self.thread == null) return;
|
||||||
|
|
||||||
// Mark that we want to terminate
|
// Mark that we want to terminate
|
||||||
self.terminate.store(true, .SeqCst);
|
self.terminate.store(true, .SeqCst);
|
||||||
|
|
||||||
// Post to the semaphore to ensure that any waits are processed.
|
// Post to the semaphore to ensure that any waits are processed.
|
||||||
self.sem.post();
|
self.sem.post();
|
||||||
|
}
|
||||||
|
|
||||||
// Wait
|
/// Wait for the thread backing the embedding to end.
|
||||||
try thread.join();
|
pub fn join(self: *Embed) !void {
|
||||||
|
if (self.thread) |*thr| {
|
||||||
|
try thr.join();
|
||||||
self.thread = null;
|
self.thread = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// loopRun runs the next tick of the libuv event loop. This should be
|
/// loopRun runs the next tick of the libuv event loop. This should be
|
||||||
/// called by the main loop thread as a result of callback making some
|
/// called by the main loop thread as a result of callback making some
|
||||||
@ -77,7 +80,6 @@ fn threadMain(self: *Embed) void {
|
|||||||
switch (builtin.os.tag) {
|
switch (builtin.os.tag) {
|
||||||
// epoll
|
// epoll
|
||||||
.linux => {
|
.linux => {
|
||||||
std.log.info("FOO {} {}", .{ fd, timeout });
|
|
||||||
var ev: [1]std.os.linux.epoll_event = undefined;
|
var ev: [1]std.os.linux.epoll_event = undefined;
|
||||||
while (std.os.epoll_wait(fd, &ev, timeout) == -1) {}
|
while (std.os.epoll_wait(fd, &ev, timeout) == -1) {}
|
||||||
},
|
},
|
||||||
@ -105,5 +107,6 @@ test "Embed" {
|
|||||||
// This just tests that the thread can start and then stop.
|
// This just tests that the thread can start and then stop.
|
||||||
// It doesn't do much else at the moment
|
// It doesn't do much else at the moment
|
||||||
try embed.start();
|
try embed.start();
|
||||||
try embed.stop();
|
embed.stop();
|
||||||
|
try embed.join();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user