@@ -26,15 +26,15 @@ use error::{self, Error, Result};
2626/// An opaque type that represents a Future in the FoundationDB C API.
2727pub ( crate ) struct FdbFuture {
2828 f : Option < * mut fdb:: FDBFuture > ,
29- task : Option < Box < futures :: task :: Task > > ,
29+ cb_active : bool ,
3030}
3131
3232impl FdbFuture {
3333 // `new` is marked as unsafe because it's lifetime is not well-defined.
3434 pub ( crate ) unsafe fn new ( f : * mut fdb:: FDBFuture ) -> Self {
3535 Self {
3636 f : Some ( f) ,
37- task : None ,
37+ cb_active : false ,
3838 }
3939 }
4040}
@@ -56,14 +56,14 @@ impl futures::Future for FdbFuture {
5656 fn poll ( & mut self ) -> std:: result:: Result < Async < Self :: Item > , Self :: Error > {
5757 let f = self . f . expect ( "cannot poll after resolve" ) ;
5858
59- if self . task . is_none ( ) {
59+ if ! self . cb_active {
6060 let task = futures:: task:: current ( ) ;
6161 let task = Box :: new ( task) ;
62- let task_ptr = task . as_ref ( ) as * const _ ;
62+ let task_ptr = Box :: into_raw ( task ) ;
6363 unsafe {
6464 fdb:: fdb_future_set_callback ( f, Some ( fdb_future_callback) , task_ptr as * mut _ ) ;
6565 }
66- self . task = Some ( task ) ;
66+ self . cb_active = true ;
6767
6868 return Ok ( Async :: NotReady ) ;
6969 }
@@ -81,14 +81,16 @@ impl futures::Future for FdbFuture {
8181 }
8282}
8383
84+ unsafe impl Send for FdbFuture { }
85+ unsafe impl Sync for FdbFuture { }
86+
8487// The callback from fdb C API can be called from multiple threads. so this callback should be
8588// thread-safe.
8689extern "C" fn fdb_future_callback (
8790 _f : * mut fdb:: FDBFuture ,
8891 callback_parameter : * mut :: std:: os:: raw:: c_void ,
8992) {
90- let task: * const futures:: task:: Task = callback_parameter as * const _ ;
91- let task: & futures:: task:: Task = unsafe { & * task } ;
93+ let task = unsafe { Box :: from_raw ( callback_parameter as * mut futures:: task:: Task ) } ;
9294 task. notify ( ) ;
9395}
9496
0 commit comments