@@ -62,11 +62,10 @@ impl FileDescription for Event {
62
62
return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
63
63
}
64
64
65
- // eventfd read at the size of u64 .
65
+ // Turn the pointer into a place at the right type .
66
66
let buf_place = ecx. ptr_to_mplace_unaligned ( ptr, ty) ;
67
67
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)
70
69
}
71
70
72
71
/// A write call adds the 8-byte integer value supplied in
@@ -97,18 +96,10 @@ impl FileDescription for Event {
97
96
return ecx. set_last_error_and_return ( ErrorKind :: InvalidInput , dest) ;
98
97
}
99
98
100
- // Read the user-supplied value from the pointer .
99
+ // Turn the pointer into a place at the right type .
101
100
let buf_place = ecx. ptr_to_mplace_unaligned ( ptr, ty) ;
102
- let num = ecx. read_scalar ( & buf_place) ?. to_u64 ( ) ?;
103
101
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)
112
103
}
113
104
114
105
fn as_unix ( & self ) -> & dyn UnixFileDescription {
@@ -193,20 +184,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
193
184
/// Block thread if the value addition will exceed u64::MAX -1,
194
185
/// else just add the user-supplied value to current counter.
195
186
fn eventfd_write < ' tcx > (
196
- num : u64 ,
197
187
buf_place : MPlaceTy < ' tcx > ,
198
188
dest : & MPlaceTy < ' tcx > ,
199
- weak_eventfd : WeakFileDescriptionRef ,
189
+ eventfd_ref : & FileDescriptionRef ,
200
190
ecx : & mut MiriInterpCx < ' tcx > ,
201
191
) -> InterpResult < ' tcx > {
202
- let Some ( eventfd_ref) = weak_eventfd. upgrade ( ) else {
203
- throw_unsup_format ! ( "eventfd FD got closed while blocking." )
204
- } ;
205
-
206
192
// Since we pass the weak file description ref, it is guaranteed to be
207
193
// an eventfd file description.
208
194
let eventfd = eventfd_ref. downcast :: < Event > ( ) . unwrap ( ) ;
209
195
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
+
210
203
match eventfd. counter . get ( ) . checked_add ( num) {
211
204
Some ( new_count @ 0 ..=MAX_COUNTER ) => {
212
205
// Future `read` calls will synchronize with this write, so update the FD clock.
@@ -219,7 +212,7 @@ fn eventfd_write<'tcx>(
219
212
220
213
// The state changed; we check and update the status of all supported event
221
214
// types for current file description.
222
- ecx. check_and_update_readiness ( & eventfd_ref) ?;
215
+ ecx. check_and_update_readiness ( eventfd_ref) ?;
223
216
224
217
// Unblock *all* threads previously blocked on `read`.
225
218
// We need to take out the blocked thread ids and unblock them together,
@@ -244,6 +237,7 @@ fn eventfd_write<'tcx>(
244
237
245
238
eventfd. blocked_write_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
246
239
240
+ let weak_eventfd = eventfd_ref. downgrade ( ) ;
247
241
ecx. block_thread (
248
242
BlockReason :: Eventfd ,
249
243
None ,
@@ -255,8 +249,10 @@ fn eventfd_write<'tcx>(
255
249
weak_eventfd: WeakFileDescriptionRef ,
256
250
}
257
251
@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)
260
256
}
261
257
) ,
262
258
) ;
@@ -270,13 +266,9 @@ fn eventfd_write<'tcx>(
270
266
fn eventfd_read < ' tcx > (
271
267
buf_place : MPlaceTy < ' tcx > ,
272
268
dest : & MPlaceTy < ' tcx > ,
273
- weak_eventfd : WeakFileDescriptionRef ,
269
+ eventfd_ref : & FileDescriptionRef ,
274
270
ecx : & mut MiriInterpCx < ' tcx > ,
275
271
) -> InterpResult < ' tcx > {
276
- let Some ( eventfd_ref) = weak_eventfd. upgrade ( ) else {
277
- throw_unsup_format ! ( "eventfd FD got closed while blocking." )
278
- } ;
279
-
280
272
// Since we pass the weak file description ref to the callback function, it is guaranteed to be
281
273
// an eventfd file description.
282
274
let eventfd = eventfd_ref. downcast :: < Event > ( ) . unwrap ( ) ;
@@ -293,6 +285,7 @@ fn eventfd_read<'tcx>(
293
285
294
286
eventfd. blocked_read_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
295
287
288
+ let weak_eventfd = eventfd_ref. downgrade ( ) ;
296
289
ecx. block_thread (
297
290
BlockReason :: Eventfd ,
298
291
None ,
@@ -303,8 +296,10 @@ fn eventfd_read<'tcx>(
303
296
weak_eventfd: WeakFileDescriptionRef ,
304
297
}
305
298
@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)
308
303
}
309
304
) ,
310
305
) ;
@@ -317,7 +312,7 @@ fn eventfd_read<'tcx>(
317
312
318
313
// The state changed; we check and update the status of all supported event
319
314
// types for current file description.
320
- ecx. check_and_update_readiness ( & eventfd_ref) ?;
315
+ ecx. check_and_update_readiness ( eventfd_ref) ?;
321
316
322
317
// Unblock *all* threads previously blocked on `write`.
323
318
// We need to take out the blocked thread ids and unblock them together,
0 commit comments