@@ -62,11 +62,10 @@ impl FileDescription for Event {
6262 return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
6363 }
6464
65- // eventfd read at the size of u64 .
65+ // Turn the pointer into a place at the right type .
6666 let buf_place = ecx. ptr_to_mplace_unaligned ( ptr, ty) ;
6767
68- let weak_eventfd = self_ref. downgrade ( ) ;
69- eventfd_read ( buf_place, dest, weak_eventfd, ecx)
68+ eventfd_read ( buf_place, dest, self_ref, ecx)
7069 }
7170
7271 /// A write call adds the 8-byte integer value supplied in
@@ -97,18 +96,10 @@ impl FileDescription for Event {
9796 return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
9897 }
9998
100- // Read the user-supplied value from the pointer .
99+ // Turn the pointer into a place at the right type .
101100 let buf_place = ecx. ptr_to_mplace_unaligned ( ptr, ty) ;
102- let num = ecx. read_scalar ( & buf_place) ?. to_u64 ( ) ?;
103101
104- // u64::MAX as input is invalid because the maximum value of counter is u64::MAX - 1.
105- if num == u64:: MAX {
106- return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
107- }
108- // If the addition does not let the counter to exceed the maximum value, update the counter.
109- // Else, block.
110- let weak_eventfd = self_ref. downgrade ( ) ;
111- eventfd_write ( num, buf_place, dest, weak_eventfd, ecx)
102+ eventfd_write ( buf_place, dest, self_ref, ecx)
112103 }
113104
114105 fn as_unix ( & self ) -> & dyn UnixFileDescription {
@@ -193,20 +184,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
193184/// Block thread if the value addition will exceed u64::MAX -1,
194185/// else just add the user-supplied value to current counter.
195186fn eventfd_write < ' tcx > (
196- num : u64 ,
197187 buf_place : MPlaceTy < ' tcx > ,
198188 dest : & MPlaceTy < ' tcx > ,
199- weak_eventfd : WeakFileDescriptionRef ,
189+ eventfd_ref : & FileDescriptionRef ,
200190 ecx : & mut MiriInterpCx < ' tcx > ,
201191) -> InterpResult < ' tcx > {
202- let Some ( eventfd_ref) = weak_eventfd. upgrade ( ) else {
203- throw_unsup_format ! ( "eventfd FD got closed while blocking." )
204- } ;
205-
206192 // Since we pass the weak file description ref, it is guaranteed to be
207193 // an eventfd file description.
208194 let eventfd = eventfd_ref. downcast :: < Event > ( ) . unwrap ( ) ;
209195
196+ // Figure out which value we should add.
197+ let num = ecx. read_scalar ( & buf_place) ?. to_u64 ( ) ?;
198+ // u64::MAX as input is invalid because the maximum value of counter is u64::MAX - 1.
199+ if num == u64:: MAX {
200+ return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
201+ }
202+
210203 match eventfd. counter . get ( ) . checked_add ( num) {
211204 Some ( new_count @ 0 ..=MAX_COUNTER ) => {
212205 // Future `read` calls will synchronize with this write, so update the FD clock.
@@ -219,7 +212,7 @@ fn eventfd_write<'tcx>(
219212
220213 // The state changed; we check and update the status of all supported event
221214 // types for current file description.
222- ecx. check_and_update_readiness ( & eventfd_ref) ?;
215+ ecx. check_and_update_readiness ( eventfd_ref) ?;
223216
224217 // Unblock *all* threads previously blocked on `read`.
225218 // We need to take out the blocked thread ids and unblock them together,
@@ -244,6 +237,7 @@ fn eventfd_write<'tcx>(
244237
245238 eventfd. blocked_write_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
246239
240+ let weak_eventfd = eventfd_ref. downgrade ( ) ;
247241 ecx. block_thread (
248242 BlockReason :: Eventfd ,
249243 None ,
@@ -255,8 +249,10 @@ fn eventfd_write<'tcx>(
255249 weak_eventfd: WeakFileDescriptionRef ,
256250 }
257251 @unblock = |this| {
258- // When we get unblocked, try again.
259- eventfd_write( num, buf_place, & dest, weak_eventfd, this)
252+ // When we get unblocked, try again. We know the ref is still valid,
253+ // otherwise there couldn't be a `write` that unblocks us.
254+ let eventfd_ref = weak_eventfd. upgrade( ) . unwrap( ) ;
255+ eventfd_write( buf_place, & dest, & eventfd_ref, this)
260256 }
261257 ) ,
262258 ) ;
@@ -270,13 +266,9 @@ fn eventfd_write<'tcx>(
270266fn eventfd_read < ' tcx > (
271267 buf_place : MPlaceTy < ' tcx > ,
272268 dest : & MPlaceTy < ' tcx > ,
273- weak_eventfd : WeakFileDescriptionRef ,
269+ eventfd_ref : & FileDescriptionRef ,
274270 ecx : & mut MiriInterpCx < ' tcx > ,
275271) -> InterpResult < ' tcx > {
276- let Some ( eventfd_ref) = weak_eventfd. upgrade ( ) else {
277- throw_unsup_format ! ( "eventfd FD got closed while blocking." )
278- } ;
279-
280272 // Since we pass the weak file description ref to the callback function, it is guaranteed to be
281273 // an eventfd file description.
282274 let eventfd = eventfd_ref. downcast :: < Event > ( ) . unwrap ( ) ;
@@ -293,6 +285,7 @@ fn eventfd_read<'tcx>(
293285
294286 eventfd. blocked_read_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
295287
288+ let weak_eventfd = eventfd_ref. downgrade ( ) ;
296289 ecx. block_thread (
297290 BlockReason :: Eventfd ,
298291 None ,
@@ -303,8 +296,10 @@ fn eventfd_read<'tcx>(
303296 weak_eventfd: WeakFileDescriptionRef ,
304297 }
305298 @unblock = |this| {
306- // When we get unblocked, try again.
307- eventfd_read( buf_place, & dest, weak_eventfd, this)
299+ // When we get unblocked, try again. We know the ref is still valid,
300+ // otherwise there couldn't be a `write` that unblocks us.
301+ let eventfd_ref = weak_eventfd. upgrade( ) . unwrap( ) ;
302+ eventfd_read( buf_place, & dest, & eventfd_ref, this)
308303 }
309304 ) ,
310305 ) ;
@@ -317,7 +312,7 @@ fn eventfd_read<'tcx>(
317312
318313 // The state changed; we check and update the status of all supported event
319314 // types for current file description.
320- ecx. check_and_update_readiness ( & eventfd_ref) ?;
315+ ecx. check_and_update_readiness ( eventfd_ref) ?;
321316
322317 // Unblock *all* threads previously blocked on `write`.
323318 // We need to take out the blocked thread ids and unblock them together,
0 commit comments