mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 17:26:09 +03:00
allocate data for paste data if its too large
This commit is contained in:
@ -816,10 +816,10 @@ fn keyCallback(
|
|||||||
}, .{ .forever = {} });
|
}, .{ .forever = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: NO! ALLOCATE THIS
|
_ = win.io_thread.mailbox.push(termio.message.IO.writeReq(
|
||||||
_ = win.io_thread.mailbox.push(.{
|
win.alloc,
|
||||||
.write_stable = data,
|
data,
|
||||||
}, .{ .forever = {} });
|
) catch unreachable, .{ .forever = {} });
|
||||||
|
|
||||||
if (bracketed) {
|
if (bracketed) {
|
||||||
_ = win.io_thread.mailbox.push(.{
|
_ = win.io_thread.mailbox.push(.{
|
||||||
|
@ -164,6 +164,10 @@ fn drainMailbox(self: *Thread) !void {
|
|||||||
.resize => |v| try self.impl.resize(v.grid_size, v.screen_size),
|
.resize => |v| try self.impl.resize(v.grid_size, v.screen_size),
|
||||||
.write_small => |v| try self.impl.queueWrite(v.data[0..v.len]),
|
.write_small => |v| try self.impl.queueWrite(v.data[0..v.len]),
|
||||||
.write_stable => |v| try self.impl.queueWrite(v),
|
.write_stable => |v| try self.impl.queueWrite(v),
|
||||||
|
.write_alloc => |v| {
|
||||||
|
defer v.alloc.free(v.data);
|
||||||
|
try self.impl.queueWrite(v.data);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
|
|
||||||
/// The messages that can be sent to an IO thread.
|
/// The messages that can be sent to an IO thread.
|
||||||
|
///
|
||||||
|
/// This is not a tiny structure (~40 bytes at the time of writing this comment),
|
||||||
|
/// but the messages are IO thread sends are also very few. At the current size
|
||||||
|
/// we can queue 26,000 messages before consuming a MB of RAM.
|
||||||
pub const IO = union(enum) {
|
pub const IO = union(enum) {
|
||||||
/// Resize the window.
|
/// Resize the window.
|
||||||
resize: struct {
|
resize: struct {
|
||||||
@ -16,12 +21,52 @@ pub const IO = union(enum) {
|
|||||||
|
|
||||||
/// Write where the data pointer is stable.
|
/// Write where the data pointer is stable.
|
||||||
write_stable: []const u8,
|
write_stable: []const u8,
|
||||||
|
|
||||||
|
/// Write where the data is allocated and must be freed.
|
||||||
|
write_alloc: WriteReq.Alloc,
|
||||||
|
|
||||||
|
/// Return a write request for the given data. This will use
|
||||||
|
/// write_small if it fits or write_alloc otherwise. This should NOT
|
||||||
|
/// be used for stable pointers which can be manually set to write_stable.
|
||||||
|
pub fn writeReq(alloc: Allocator, data: anytype) !IO {
|
||||||
|
switch (@typeInfo(@TypeOf(data))) {
|
||||||
|
.Pointer => |info| {
|
||||||
|
assert(info.size == .Slice);
|
||||||
|
assert(info.child == u8);
|
||||||
|
|
||||||
|
// If it fits in our small request, do that.
|
||||||
|
if (data.len <= WriteReq.Small.Max) {
|
||||||
|
var buf: WriteReq.Small.Array = undefined;
|
||||||
|
std.mem.copy(u8, &buf, data);
|
||||||
|
return IO{
|
||||||
|
.write_small = .{
|
||||||
|
.data = buf,
|
||||||
|
.len = @intCast(u8, data.len),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, allocate
|
||||||
|
var buf = try alloc.dupe(u8, data);
|
||||||
|
errdefer alloc.free(buf);
|
||||||
|
return IO{
|
||||||
|
.write_alloc = .{
|
||||||
|
.alloc = alloc,
|
||||||
|
.data = buf,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a write request.
|
/// Represents a write request.
|
||||||
pub const WriteReq = union(enum) {
|
pub const WriteReq = union(enum) {
|
||||||
pub const Small = struct {
|
pub const Small = struct {
|
||||||
pub const Array = [22]u8;
|
pub const Max = 38;
|
||||||
|
pub const Array = [Max]u8;
|
||||||
data: Array,
|
data: Array,
|
||||||
len: u8,
|
len: u8,
|
||||||
};
|
};
|
||||||
@ -43,8 +88,31 @@ pub const WriteReq = union(enum) {
|
|||||||
alloc: Alloc,
|
alloc: Alloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test {
|
||||||
|
std.testing.refAllDecls(@This());
|
||||||
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
// Ensure we don't grow our IO message size without explicitly wanting to.
|
// Ensure we don't grow our IO message size without explicitly wanting to.
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
try testing.expectEqual(@as(usize, 24), @sizeOf(IO));
|
try testing.expectEqual(@as(usize, 40), @sizeOf(IO));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "IO.writeReq small" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
const input = "hello!";
|
||||||
|
const io = try IO.writeReq(alloc, @as([]const u8, input));
|
||||||
|
try testing.expect(io == .write_small);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "IO.writeReq alloc" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
const input = "hello! " ** 100;
|
||||||
|
const io = try IO.writeReq(alloc, @as([]const u8, input));
|
||||||
|
try testing.expect(io == .write_alloc);
|
||||||
|
io.write_alloc.alloc.free(io.write_alloc.data);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user