mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
termio: wake up writer thread if the writer mailbox is full
Normally, we queue all the writes we need from a single `read()` syscall and only wake up the writer thread at the end of processing that batch of data. But under very heavy load or large batches of data, it is possible for the terminal sequences to generate enough writes to the pty to fill the writer thread queue while we're still processing the data from `read()`. This modifies our queuer to attempt to queue, but if the queue is full we wake up the writer thread immediately then queue again (which should succeed in every case -- eventually).
This commit is contained in:
@ -60,7 +60,9 @@ pub fn Stream(comptime Handler: type) type {
|
||||
for (actions) |action_opt| {
|
||||
const action = action_opt orelse continue;
|
||||
|
||||
// if (action != .print) {
|
||||
// log.info("action: {}", .{action});
|
||||
// }
|
||||
|
||||
// If this handler handles everything manually then we do nothing
|
||||
// if it can be processed.
|
||||
|
@ -1398,7 +1398,21 @@ const StreamHandler = struct {
|
||||
}
|
||||
|
||||
inline fn messageWriter(self: *StreamHandler, msg: termio.Message) void {
|
||||
// Try to write to the mailbox with an instant timeout. If the
|
||||
// mailbox is full, then we wake up the writer thread mid-processing
|
||||
// so it can process the message and then try again with a forever
|
||||
// wait.
|
||||
if (self.ev.writer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
||||
self.ev.writer_wakeup.notify() catch |err| {
|
||||
log.warn("failed to wake up writer, data will be dropped err={}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
_ = self.ev.writer_mailbox.push(msg, .{ .forever = {} });
|
||||
}
|
||||
|
||||
// Normally, we just flag this true to wake up the writer thread
|
||||
// once per batch of data.
|
||||
self.writer_messaged = true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user