mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Add `bun.ptr.ExternalShared`, a shared pointer whose reference count is
managed externally; e.g., by extern functions. This can be used to work
with `RefCounted` C++ objects in Zig. For example:
```cpp
// C++:
struct MyType : RefCounted<MyType> { ... };
extern "C" void MyType__ref(MyType* self) { self->ref(); }
extern "C" void MyType__ref(MyType* self) { self->deref(); }
```
```zig
// Zig:
const MyType = opaque {
extern fn MyType__ref(self: *MyType) void;
extern fn MyType__deref(self: *MyType) void;
pub const Ref = bun.ptr.ExternalShared(MyType);
// This enables `ExternalShared` to work.
pub const external_shared_descriptor = struct {
pub const ref = MyType__ref;
pub const deref = MyType__deref;
};
};
// Now `MyType.Ref` behaves just like `Ref<MyType>` in C++:
var some_ref: MyType.Ref = someFunctionReturningMyTypeRef();
const ptr: *MyType = some_ref.get(); // gets the inner pointer
var some_other_ref = some_ref.clone(); // increments the ref count
some_ref.deinit(); // decrements the ref count
// decrements the ref count again; if no other refs exist, the object
// is destroyed
some_other_ref.deinit();
```
This commit also adds `RawRefCount`, a simple wrapper around an integer
reference count that can be used to implement the interface required by
`ExternalShared`. Generally, for reference-counted Zig types,
`bun.ptr.Shared` is preferred, but occasionally it is useful to have an
“intrusive” reference-counted type where the ref count is stored in the
type itself. For this purpose, `ExternalShared` + `RawRefCount` is more
flexible and less error-prone than the deprecated `bun.ptr.RefCounted`
type.
(For internal tracking: fixes STAB-1287, STAB-1288)
34 lines
1.5 KiB
Zig
34 lines
1.5 KiB
Zig
//! The `ptr` module contains smart pointer types that are used throughout Bun.
|
|
pub const Cow = @import("./ptr/Cow.zig").Cow;
|
|
|
|
pub const CowSlice = @import("./ptr/CowSlice.zig").CowSlice;
|
|
pub const CowSliceZ = @import("./ptr/CowSlice.zig").CowSliceZ;
|
|
pub const CowString = CowSlice(u8);
|
|
|
|
pub const owned = @import("./ptr/owned.zig");
|
|
pub const Owned = owned.Owned; // owned pointer allocated with default allocator
|
|
pub const OwnedIn = owned.OwnedIn; // owned pointer allocated with specific type of allocator
|
|
pub const DynamicOwned = owned.Dynamic; // owned pointer allocated with any `std.mem.Allocator`
|
|
|
|
pub const shared = @import("./ptr/shared.zig");
|
|
pub const Shared = shared.Shared;
|
|
pub const AtomicShared = shared.AtomicShared;
|
|
pub const ExternalShared = @import("./ptr/external_shared.zig").ExternalShared;
|
|
|
|
pub const ref_count = @import("./ptr/ref_count.zig");
|
|
/// Deprecated; use `Shared(*T)`.
|
|
pub const RefCount = ref_count.RefCount;
|
|
/// Deprecated; use `AtomicShared(*T)`.
|
|
pub const ThreadSafeRefCount = ref_count.ThreadSafeRefCount;
|
|
/// Deprecated; use `Shared(*T)`.
|
|
pub const RefPtr = ref_count.RefPtr;
|
|
|
|
pub const raw_ref_count = @import("./ptr/raw_ref_count.zig");
|
|
pub const RawRefCount = raw_ref_count.RawRefCount;
|
|
|
|
pub const TaggedPointer = @import("./ptr/tagged_pointer.zig").TaggedPointer;
|
|
pub const TaggedPointerUnion = @import("./ptr/tagged_pointer.zig").TaggedPointerUnion;
|
|
|
|
/// Deprecated; use `Shared(*T).Weak`.
|
|
pub const WeakPtr = @import("./ptr/weak_ptr.zig").WeakPtr;
|