Skip to content

Commit e5efd2d

Browse files
committed
future: pass future pointer to callback directly
Before this PR, the pointer was obtained from a valid reference &CassFuture, which is totally fine. However, I want to reduce the ways one can obtain such pointer. For ArcFFI (shared pointers), I want them to be obtainable only in two ways: - `ArcFFI::as_ptr()` which accepts an &Arc - from the user, as a function parameter This way, we are guaranteed that the pointer comes from a valid Arc allocation (unless user provided pointer to some garbage, but there is no much we can do about it). If we assume that user provides a pointer returned from some prior call to API, we are guaranteed that it is valid, and comes from an Arc allocation (or is null). I don't want to allow ArcFFI api to create a pointer from a refernce, to prevent creating a pointer, from example from stack allocated object: ``` let future = CassFuture { ... }; let future_ptr = ArcFFI::as_ptr(&future); ``` This commit may not make much sense now, but all should be clear once I introduce traits restricting the pointer types later in this PR.
1 parent b03d735 commit e5efd2d

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

scylla-rust-wrapper/src/future.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ struct BoundCallback {
4040
unsafe impl Send for BoundCallback {}
4141

4242
impl BoundCallback {
43-
fn invoke(self, fut: &CassFuture) {
43+
fn invoke(self, fut_ptr: *const CassFuture) {
4444
unsafe {
45-
self.cb.unwrap()(fut as *const CassFuture, self.data);
45+
self.cb.unwrap()(fut_ptr, self.data);
4646
}
4747
}
4848
}
@@ -96,7 +96,8 @@ impl CassFuture {
9696
guard.callback.take()
9797
};
9898
if let Some(bound_cb) = maybe_cb {
99-
bound_cb.invoke(cass_fut_clone.as_ref());
99+
let fut_ptr = ArcFFI::as_ptr(&cass_fut_clone);
100+
bound_cb.invoke(fut_ptr);
100101
}
101102

102103
cass_fut_clone.wait_for_value.notify_all();
@@ -258,7 +259,12 @@ impl CassFuture {
258259
}
259260
}
260261

261-
pub fn set_callback(&self, cb: CassFutureCallback, data: *mut c_void) -> CassError {
262+
pub fn set_callback(
263+
&self,
264+
self_ptr: *const CassFuture,
265+
cb: CassFutureCallback,
266+
data: *mut c_void,
267+
) -> CassError {
262268
let mut lock = self.state.lock().unwrap();
263269
if lock.callback.is_some() {
264270
// Another callback has been already set
@@ -268,7 +274,7 @@ impl CassFuture {
268274
if lock.value.is_some() {
269275
// The value is already available, we need to call the callback ourselves
270276
mem::drop(lock);
271-
bound_cb.invoke(self);
277+
bound_cb.invoke(self_ptr);
272278
return CassError::CASS_OK;
273279
}
274280
// Store the callback
@@ -293,7 +299,7 @@ pub unsafe extern "C" fn cass_future_set_callback(
293299
callback: CassFutureCallback,
294300
data: *mut ::std::os::raw::c_void,
295301
) -> CassError {
296-
ArcFFI::as_ref(future_raw).set_callback(callback, data)
302+
ArcFFI::as_ref(future_raw).set_callback(future_raw, callback, data)
297303
}
298304

299305
#[no_mangle]

0 commit comments

Comments
 (0)