11use core:: ptr;
2- use core:: mem:: { forget, size_of} ;
2+ use core:: mem:: { self , forget, size_of} ;
33use core:: marker:: PhantomData ;
44use core:: cell:: Cell ;
55use super :: Unpark ;
@@ -54,9 +54,9 @@ pub const MAX_UNPARK_BYTES : usize = _MAX_UNPARK_BYTES;
5454/// A VTable that knows how to clone because the data has a maximum size.
5555#[ derive( Copy ) ]
5656struct UnparkVtable {
57- unpark : fn ( * const ( ) ) ,
58- clone_to_byte_buffer : fn ( * const ( ) ) -> [ u8 ; MAX_UNPARK_BYTES ] ,
59- drop_in_place : unsafe fn ( * mut ( ) ) ,
57+ unpark : unsafe fn ( * const ( ) ) ,
58+ clone_to_byte_buffer : unsafe fn ( * const ( ) ) -> [ u8 ; MAX_UNPARK_BYTES ] ,
59+ manual_drop : unsafe fn ( * const ( ) ) ,
6060}
6161
6262impl Clone for UnparkVtable {
@@ -67,29 +67,31 @@ impl Clone for UnparkVtable {
6767
6868impl UnparkVtable {
6969 fn new < T : Unpark + Clone > ( ) -> UnparkVtable {
70- assert ! ( size_of:: <T >( ) <= MAX_UNPARK_BYTES ) ;
7170 UnparkVtable {
7271 unpark : Self :: call_unpark :: < T > ,
7372 clone_to_byte_buffer : Self :: clone_to_byte_buffer :: < T > ,
74- drop_in_place : Self :: drop_in_place :: < T > ,
73+ manual_drop : Self :: manual_drop :: < T > ,
7574 }
7675 }
7776
78- fn call_unpark < T : Unpark > ( data : * const ( ) ) {
79- let downcasted = unsafe { & * ( data as * const _ as * const T ) } ;
80- downcasted. unpark ( )
77+ /// Safe if data points to T.
78+ unsafe fn call_unpark < T : Unpark > ( data : * const ( ) ) {
79+ let downcasted = read_unaligned ( data as * const _ as * const T ) ;
80+ downcasted. unpark ( ) ;
81+ forget ( downcasted)
8182 }
8283
83- /// Returns array with bytes of the cloned data. Safe if data is shorter than MAX_UNPARK_BYTES .
84+ /// Returns array with bytes of the cloned data. Safe if data points to T .
8485 /// The caller owns the new data and is responsible for dropping it with `drop_in_place<T>`.
85- fn clone_to_byte_buffer < T : Clone > ( data : * const ( ) ) -> [ u8 ; MAX_UNPARK_BYTES ] {
86- let downcasted = unsafe { & * ( data as * const _ as * const T ) } ;
87- obliviate ( downcasted. clone ( ) )
86+ unsafe fn clone_to_byte_buffer < T : Clone > ( data : * const ( ) ) -> [ u8 ; MAX_UNPARK_BYTES ] {
87+ let downcasted = read_unaligned ( data as * const _ as * const T ) ;
88+ let raw = obliviate ( downcasted. clone ( ) ) ;
89+ forget ( downcasted) ;
90+ raw
8891 }
8992
90- /// Make sure the original value is forgotten to avoid double free.
91- unsafe fn drop_in_place < T > ( data : * mut ( ) ) {
92- ptr:: drop_in_place ( & mut * ( data as * mut _ as * mut T ) ) ;
93+ unsafe fn manual_drop < T > ( data : * const ( ) ) {
94+ read_unaligned ( data as * const _ as * const T ) ;
9395 }
9496}
9597
@@ -143,23 +145,25 @@ impl UnparkHandle {
143145impl Drop for UnparkHandle {
144146 fn drop ( & mut self ) {
145147 unsafe {
146- ( self . vtable . drop_in_place ) ( & mut self . data as * mut _ as * mut ( ) ) ;
148+ ( self . vtable . manual_drop ) ( & self . data as * const _ as * const ( ) ) ;
147149 }
148150 }
149151}
150152
151153impl Clone for UnparkHandle {
152154 fn clone ( & self ) -> Self {
153155 UnparkHandle {
154- data : ( self . vtable . clone_to_byte_buffer ) ( & self . data as * const _ as * const ( ) ) ,
156+ data : unsafe { ( self . vtable . clone_to_byte_buffer ) ( & self . data as * const _ as * const ( ) ) } ,
155157 ..* self
156158 }
157159 }
158160}
159161
160162impl Unpark for UnparkHandle {
161163 fn unpark ( & self ) {
162- ( self . vtable . unpark ) ( & self . data as * const _ as * const ( ) )
164+ unsafe {
165+ ( self . vtable . unpark ) ( & self . data as * const _ as * const ( ) )
166+ }
163167 }
164168}
165169
@@ -178,3 +182,13 @@ fn obliviate<T>(victim : T) -> [u8; MAX_UNPARK_BYTES] {
178182 forget ( victim) ;
179183 buffer
180184}
185+
186+ /// As implemented in core::ptr.
187+ /// When we drop support for rust < 1.17, use core::ptr::read_unaligned instead.
188+ unsafe fn read_unaligned < T > ( src : * const T ) -> T {
189+ let mut tmp: T = mem:: uninitialized ( ) ;
190+ ptr:: copy_nonoverlapping ( src as * const u8 ,
191+ & mut tmp as * mut T as * mut u8 ,
192+ size_of :: < T > ( ) ) ;
193+ tmp
194+ }
0 commit comments