11//! `GcdFile`: per-file I/O against a `DispatchIO` channel.
22//!
33//! The channel is created in `DISPATCH_IO_RANDOM` mode and owns a duplicated
4- //! file descriptor (so dispatch_io can asynchronously close its own copy when
4+ //! file descriptor (so ` dispatch_io` can asynchronously close its own copy when
55//! the channel is released, independently of the `std::fs::File` we hold).
66//! Reads and writes call `dispatch_io_read` / `dispatch_io_write` with block
77//! handlers; the handlers accumulate chunks and, on `done`, send the result
@@ -14,7 +14,7 @@ use std::sync::Arc;
1414
1515use parking_lot:: Mutex ;
1616
17- use block2:: { Block , DynBlock , RcBlock } ;
17+ use block2:: { DynBlock , RcBlock } ;
1818use dispatch2:: { DispatchData , DispatchIO , DispatchIOCloseFlags , DispatchQueue , DispatchRetained } ;
1919
2020use crate :: Result ;
@@ -135,16 +135,10 @@ fn submit_read(
135135 }
136136 } ) ;
137137
138- // SAFETY: transmute is from the stand-in block signature to the typedef
139- // declared by dispatch2 — the ABI is identical because `bool` and `u8`
140- // share the same one-byte ABI, and a `*mut DispatchData` is bit-identical
141- // to a `*mut c_void`.
142- let handler_ptr: * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > = unsafe {
143- std:: mem:: transmute :: <
144- * mut Block < dyn Fn ( u8 , * mut c_void , libc:: c_int ) > ,
145- * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > ,
146- > ( RcBlock :: as_ptr ( & handler) )
147- } ;
138+ // SAFETY: ABI-compatible pointer cast to the typedef declared by dispatch2.
139+ // `bool` and `u8` are one byte, while both data arguments are pointers.
140+ let handler_ptr: * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > =
141+ RcBlock :: as_ptr ( & handler) . cast :: < DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > > ( ) ;
148142
149143 // SAFETY: channel and queue are valid (owned by the caller's `GcdFile`);
150144 // the handler block is retained by libdispatch on submission.
@@ -185,13 +179,9 @@ fn submit_write(
185179 } ,
186180 ) ;
187181
188- // SAFETY: ABI-compatible transmute; see `submit_read`.
189- let handler_ptr: * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > = unsafe {
190- std:: mem:: transmute :: <
191- * mut Block < dyn Fn ( u8 , * mut c_void , libc:: c_int ) > ,
192- * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > ,
193- > ( RcBlock :: as_ptr ( & handler) )
194- } ;
182+ // SAFETY: ABI-compatible pointer cast; see `submit_read`.
183+ let handler_ptr: * mut DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > =
184+ RcBlock :: as_ptr ( & handler) . cast :: < DynBlock < dyn Fn ( bool , * mut DispatchData , libc:: c_int ) > > ( ) ;
195185
196186 // SAFETY: channel/queue/data all valid; libdispatch retains both the data
197187 // object and the handler block for the operation's duration.
0 commit comments