mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
crash: initialize sentry off-thread
This commit is contained in:
@ -10,8 +10,15 @@ const state = &@import("../global.zig").state;
|
|||||||
|
|
||||||
const log = std.log.scoped(.sentry);
|
const log = std.log.scoped(.sentry);
|
||||||
|
|
||||||
|
/// The global state for the Sentry SDK. This is unavoidable since crash
|
||||||
|
/// handling is a global process-wide thing.
|
||||||
|
var init_thread: ?std.Thread = null;
|
||||||
|
|
||||||
/// Process-wide initialization of our Sentry client.
|
/// Process-wide initialization of our Sentry client.
|
||||||
///
|
///
|
||||||
|
/// This should only be called from one thread, and deinit should be called
|
||||||
|
/// from the same thread that calls init to avoid data races.
|
||||||
|
///
|
||||||
/// PRIVACY NOTE: I want to make it very clear that Ghostty by default does
|
/// PRIVACY NOTE: I want to make it very clear that Ghostty by default does
|
||||||
/// NOT send any data over the network. We use the Sentry native SDK to collect
|
/// NOT send any data over the network. We use the Sentry native SDK to collect
|
||||||
/// crash reports and logs, but we only store them locally (see Transport).
|
/// crash reports and logs, but we only store them locally (see Transport).
|
||||||
@ -29,6 +36,24 @@ pub fn init(gpa: Allocator) !void {
|
|||||||
// std.log.err("[sentry init time] start={}us duration={}ns", .{ start_micro, end.since(start) / std.time.ns_per_us });
|
// std.log.err("[sentry init time] start={}us duration={}ns", .{ start_micro, end.since(start) / std.time.ns_per_us });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Must only start once
|
||||||
|
assert(init_thread == null);
|
||||||
|
|
||||||
|
// We use a thread for initializing Sentry because initialization takes
|
||||||
|
// ~2k ns on my M3 Max. That's not a LOT of time but it's enough to be
|
||||||
|
// 90% of our pre-App startup time. Everything Sentry is doing initially
|
||||||
|
// is safe to do on a separate thread and fast enough that its very
|
||||||
|
// likely to be done before a crash occurs.
|
||||||
|
const thr = try std.Thread.spawn(
|
||||||
|
.{},
|
||||||
|
initThread,
|
||||||
|
.{gpa},
|
||||||
|
);
|
||||||
|
thr.setName("sentry-init") catch {};
|
||||||
|
init_thread = thr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initThread(gpa: Allocator) !void {
|
||||||
var arena = std.heap.ArenaAllocator.init(gpa);
|
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
@ -73,6 +98,11 @@ pub fn init(gpa: Allocator) !void {
|
|||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
if (comptime builtin.os.tag == .windows) return;
|
if (comptime builtin.os.tag == .windows) return;
|
||||||
|
|
||||||
|
// If we're still initializing then wait for init to finish. This
|
||||||
|
// is highly unlikely since init is a very fast operation but we want
|
||||||
|
// to avoid the possibility.
|
||||||
|
const thr = init_thread orelse return;
|
||||||
|
thr.join();
|
||||||
_ = sentry.c.sentry_close();
|
_ = sentry.c.sentry_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user