Add safety improvements and encapsulation

1. Explicitly zero out bit 63 when unpacking pointer to avoid any UB
   - Added mask: ptr_bits & 0x7FFFFFFFFFFFFFFF before ptrFromInt
2. Add ConcurrentTask.auto_delete() getter to hide implementation detail
   - The fact that auto_delete is packed into next field is now internal
   - Updated event_loop.zig to use the public getter
   - Makes the API cleaner and easier to maintain
This commit is contained in:
Claude Bot
2025-11-02 12:40:41 +00:00
parent 27a6cb4fbd
commit 063a5a9775
2 changed files with 9 additions and 2 deletions

View File

@@ -321,7 +321,7 @@ pub fn tickConcurrentWithCount(this: *EventLoop) usize {
dest.deinit();
}
if (task.next.autoDelete()) {
if (task.auto_delete()) {
to_destroy = task;
}

View File

@@ -44,7 +44,8 @@ pub const PackedNext = packed struct(u64) {
pub fn get(self: PackedNext) ?*ConcurrentTask {
if (self.ptr_bits == 0) return null;
const ptr: u64 = @as(u64, self.ptr_bits);
// Explicitly zero out bit 63 to avoid any UB
const ptr: u64 = @as(u64, self.ptr_bits) & 0x7FFFFFFFFFFFFFFF;
return @as(?*ConcurrentTask, @ptrFromInt(ptr));
}
@@ -69,6 +70,12 @@ pub const Queue = bun.threading.UnboundedQueuePacked(ConcurrentTask, .next, .@"p
pub const new = bun.TrivialNew(@This());
pub const deinit = bun.TrivialDeinit(@This());
/// Returns whether this task should be automatically deleted after completion.
/// The auto_delete flag being stored in the next field is an implementation detail.
pub inline fn auto_delete(this: *const ConcurrentTask) bool {
return this.next.autoDelete();
}
pub const AutoDeinit = enum {
manual_deinit,
auto_deinit,