diff --git a/include/thespian/c/handle.h b/include/thespian/c/handle.h index fca8a84..6da6d36 100644 --- a/include/thespian/c/handle.h +++ b/include/thespian/c/handle.h @@ -18,6 +18,9 @@ typedef struct thespian_handle_t *thespian_handle; thespian_handle thespian_handle_clone(thespian_handle); void thespian_handle_destroy(thespian_handle); +/* Stable opaque actor identity (raw instance pointer). Two handles for the + same actor return the same value. Returns 0 for a null/expired handle. */ +uintptr_t thespian_handle_id(thespian_handle); thespian_result thespian_handle_send_raw(thespian_handle, cbor_buffer); thespian_result thespian_handle_send_exit(thespian_handle, c_string_view); diff --git a/include/thespian/handle.hpp b/include/thespian/handle.hpp index c86defb..80cdc98 100644 --- a/include/thespian/handle.hpp +++ b/include/thespian/handle.hpp @@ -46,4 +46,13 @@ private: auto operator==(const handle &, const handle &) -> bool; +/// Stable opaque actor identity: the raw instance pointer. Two handles for +/// the same actor return the same value. Returns 0 for expired handles. +[[nodiscard]] inline auto instance_id(const handle &h) -> uintptr_t { + // NOLINTNEXTLINE(*-reinterpret-cast) + if (auto sp = handle_ref(h).lock()) + return reinterpret_cast(sp.get()); + return 0; +} + } // namespace thespian diff --git a/src/c/handle.cpp b/src/c/handle.cpp index 8011077..1c83455 100644 --- a/src/c/handle.cpp +++ b/src/c/handle.cpp @@ -66,4 +66,13 @@ auto thespian_handle_is_expired(thespian_handle h) -> bool { h)}; return h_->expired(); } + +auto thespian_handle_id(thespian_handle h) -> uintptr_t { + thespian::handle *h_{ + reinterpret_cast( // NOLINT(*-reinterpret-cast) + h)}; + if (!h_) + return 0; + return thespian::instance_id(*h_); +} } diff --git a/src/thespian.zig b/src/thespian.zig index 588878e..22d60cc 100644 --- a/src/thespian.zig +++ b/src/thespian.zig @@ -125,6 +125,12 @@ fn Pid(comptime own: Ownership) type { return c.thespian_handle_is_expired(self.h); } + /// Stable opaque actor identity. Two handles for the same actor + /// return the same value. Returns 0 for a null/expired handle. + pub fn instance_id(self: Self) usize { + return c.thespian_handle_id(self.h); + } + pub fn wait_expired(self: Self, timeout_ns: isize) error{Timeout}!void { var max_sleep: isize = timeout_ns; while (!self.expired()) {