mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-08-26 15:41:15 +00:00
Event listener abi (#50)
This commit is contained in:
@@ -631,7 +631,8 @@ int my_timer_version(void* ctx, FFICallback callback, void* user_data, const uin
|
||||
int my_timer_complex(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
|
||||
int my_timer_schedule(void* ctx, FFICallback callback, void* user_data, const uint8_t* req_cbor, size_t req_cbor_len);
|
||||
int my_timer_destroy(void* ctx);
|
||||
void my_timer_set_event_callback(void* ctx, FFICallback callback, void* user_data);
|
||||
uint64_t my_timer_add_event_listener(void* ctx, const char* event_name, FFICallback callback, void* user_data);
|
||||
int my_timer_remove_event_listener(void* ctx, uint64_t listener_id);
|
||||
} // extern "C"
|
||||
|
||||
// ============================================================
|
||||
@@ -746,8 +747,13 @@ public:
|
||||
};
|
||||
|
||||
void setEventHandlers(Events handlers) {
|
||||
if (event_listener_id_ != 0) {
|
||||
my_timer_remove_event_listener(ptr_, event_listener_id_);
|
||||
event_listener_id_ = 0;
|
||||
}
|
||||
events_ = std::make_unique<Events>(std::move(handlers));
|
||||
my_timer_set_event_callback(ptr_, &MyTimerCtx::eventTrampoline, events_.get());
|
||||
event_listener_id_ = my_timer_add_event_listener(
|
||||
ptr_, "", &MyTimerCtx::eventTrampoline, events_.get());
|
||||
}
|
||||
|
||||
EchoResponse echo(const EchoRequest& req) const {
|
||||
@@ -806,6 +812,7 @@ private:
|
||||
void* ptr_;
|
||||
std::chrono::milliseconds timeout_;
|
||||
std::unique_ptr<Events> events_;
|
||||
uint64_t event_listener_id_ = 0;
|
||||
explicit MyTimerCtx(void* p, std::chrono::milliseconds t) : ptr_(p), timeout_(t) {}
|
||||
static void eventTrampoline(int ret, const char* msg, std::size_t len, void* ud) {
|
||||
if (!ud) return;
|
||||
|
||||
@@ -154,6 +154,7 @@ pub struct MyTimerCtx {
|
||||
ptr: *mut c_void,
|
||||
timeout: Duration,
|
||||
events: *mut Events,
|
||||
event_listener_id: u64,
|
||||
}
|
||||
|
||||
// SAFETY: The `ptr` field points to an FFIContext owned by the Nim runtime.
|
||||
@@ -190,7 +191,7 @@ impl MyTimerCtx {
|
||||
})?;
|
||||
let addr_str: String = decode_cbor(&raw_bytes)?;
|
||||
let addr: usize = addr_str.parse().map_err(|e: std::num::ParseIntError| e.to_string())?;
|
||||
Ok(Self { ptr: addr as *mut c_void, timeout, events: std::ptr::null_mut() })
|
||||
Ok(Self { ptr: addr as *mut c_void, timeout, events: std::ptr::null_mut(), event_listener_id: 0 })
|
||||
}
|
||||
|
||||
pub async fn new_async(config: TimerConfig, timeout: Duration) -> Result<Self, String> {
|
||||
@@ -202,14 +203,19 @@ impl MyTimerCtx {
|
||||
}).await?;
|
||||
let addr_str: String = decode_cbor(&raw_bytes)?;
|
||||
let addr: usize = addr_str.parse().map_err(|e: std::num::ParseIntError| e.to_string())?;
|
||||
Ok(Self { ptr: addr as *mut c_void, timeout, events: std::ptr::null_mut() })
|
||||
Ok(Self { ptr: addr as *mut c_void, timeout, events: std::ptr::null_mut(), event_listener_id: 0 })
|
||||
}
|
||||
|
||||
/// Attach typed event handlers. Replacing handlers calls the
|
||||
/// dylib's set_event_callback with a fresh trampoline target.
|
||||
/// The previously-installed Events box (if any) is dropped here,
|
||||
/// so callbacks in flight on the FFI thread must already be done.
|
||||
/// Attach typed event handlers. Each call removes any previous
|
||||
/// listener via `_remove_event_listener` before adding the new
|
||||
/// one, so the registry never holds a pointer into a freed box.
|
||||
pub fn set_event_handlers(&mut self, handlers: Events) {
|
||||
if self.event_listener_id != 0 {
|
||||
unsafe {
|
||||
let _ = ffi::my_timer_remove_event_listener(self.ptr, self.event_listener_id);
|
||||
}
|
||||
self.event_listener_id = 0;
|
||||
}
|
||||
if !self.events.is_null() {
|
||||
unsafe { drop(Box::from_raw(self.events)); }
|
||||
self.events = std::ptr::null_mut();
|
||||
@@ -217,7 +223,9 @@ impl MyTimerCtx {
|
||||
let raw = Box::into_raw(Box::new(handlers));
|
||||
self.events = raw;
|
||||
unsafe {
|
||||
ffi::my_timer_set_event_callback(self.ptr, my_timer_event_trampoline, raw as *mut c_void);
|
||||
self.event_listener_id = ffi::my_timer_add_event_listener(
|
||||
self.ptr, b"\0".as_ptr() as *const c_char,
|
||||
my_timer_event_trampoline, raw as *mut c_void);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,5 +15,6 @@ extern "C" {
|
||||
pub fn my_timer_complex(ctx: *mut c_void, callback: FFICallback, user_data: *mut c_void, req_cbor: *const u8, req_cbor_len: usize) -> c_int;
|
||||
pub fn my_timer_schedule(ctx: *mut c_void, callback: FFICallback, user_data: *mut c_void, req_cbor: *const u8, req_cbor_len: usize) -> c_int;
|
||||
pub fn my_timer_destroy(ctx: *mut c_void) -> c_int;
|
||||
pub fn my_timer_set_event_callback(ctx: *mut c_void, callback: FFICallback, user_data: *mut c_void);
|
||||
pub fn my_timer_add_event_listener(ctx: *mut c_void, event_name: *const c_char, callback: FFICallback, user_data: *mut c_void) -> u64;
|
||||
pub fn my_timer_remove_event_listener(ctx: *mut c_void, listener_id: u64) -> c_int;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user