@@ -12,17 +12,15 @@ use crate::shims::unix::UnixFileDescription;
12
12
use crate :: * ;
13
13
14
14
/// An `Epoll` file descriptor connects file handles and epoll events
15
- #[ derive( Clone , Debug , Default ) ]
15
+ #[ derive( Debug , Default ) ]
16
16
struct Epoll {
17
17
/// A map of EpollEventInterests registered under this epoll instance.
18
18
/// Each entry is differentiated using FdId and file descriptor value.
19
19
interest_list : RefCell < BTreeMap < ( FdId , i32 ) , Rc < RefCell < EpollEventInterest > > > > ,
20
20
/// A map of EpollEventInstance that will be returned when `epoll_wait` is called.
21
21
/// Similar to interest_list, the entry is also differentiated using FdId
22
22
/// and file descriptor value.
23
- // This is an Rc because EpollInterest need to hold a reference to update
24
- // it.
25
- ready_list : Rc < ReadyList > ,
23
+ ready_list : ReadyList ,
26
24
/// A list of thread ids blocked on this epoll instance.
27
25
blocked_tid : RefCell < Vec < ThreadId > > ,
28
26
}
@@ -59,7 +57,7 @@ impl EpollEventInstance {
59
57
/// see the man page:
60
58
///
61
59
/// <https://man7.org/linux/man-pages/man2/epoll_ctl.2.html>
62
- #[ derive( Clone , Debug ) ]
60
+ #[ derive( Debug ) ]
63
61
pub struct EpollEventInterest {
64
62
/// The file descriptor value of the file description registered.
65
63
/// This is only used for ready_list, to inform userspace which FD triggered an event.
@@ -73,9 +71,9 @@ pub struct EpollEventInterest {
73
71
/// but only u64 is supported for now.
74
72
/// <https://man7.org/linux/man-pages/man3/epoll_event.3type.html>
75
73
data : u64 ,
76
- /// Ready list of the epoll instance under which this EpollEventInterest is registered.
77
- ready_list : Rc < ReadyList > ,
78
74
/// The epoll file description that this EpollEventInterest is registered under.
75
+ /// This is weak to avoid cycles, but an upgrade is always guaranteed to succeed
76
+ /// because only the `Epoll` holds a strong ref to a `EpollEventInterest`.
79
77
weak_epfd : WeakFileDescriptionRef < Epoll > ,
80
78
}
81
79
@@ -273,12 +271,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
273
271
let Some ( epfd) = this. machine . fds . get ( epfd_value) else {
274
272
return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
275
273
} ;
276
- let epoll_file_description = epfd
274
+ let epfd = epfd
277
275
. downcast :: < Epoll > ( )
278
276
. ok_or_else ( || err_unsup_format ! ( "non-epoll FD passed to `epoll_ctl`" ) ) ?;
279
277
280
- let mut interest_list = epoll_file_description. interest_list . borrow_mut ( ) ;
281
- let ready_list = & epoll_file_description. ready_list ;
278
+ let mut interest_list = epfd. interest_list . borrow_mut ( ) ;
282
279
283
280
let Some ( fd_ref) = this. machine . fds . get ( fd) else {
284
281
return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
@@ -345,8 +342,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
345
342
fd_num : fd,
346
343
events,
347
344
data,
348
- ready_list : Rc :: clone ( ready_list) ,
349
- weak_epfd : FileDescriptionRef :: downgrade ( & epoll_file_description) ,
345
+ weak_epfd : FileDescriptionRef :: downgrade ( & epfd) ,
350
346
} ) ) ;
351
347
// Notification will be returned for current epfd if there is event in the file
352
348
// descriptor we registered.
@@ -379,7 +375,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
379
375
drop ( epoll_interest) ;
380
376
381
377
// Remove related epoll_interest from ready list.
382
- ready_list. mapping . borrow_mut ( ) . remove ( & epoll_key) ;
378
+ epfd . ready_list . mapping . borrow_mut ( ) . remove ( & epoll_key) ;
383
379
384
380
// Remove dangling EpollEventInterest from its global table.
385
381
// .unwrap() below should succeed because the file description id must have registered
@@ -592,14 +588,15 @@ fn check_and_update_one_event_interest<'tcx>(
592
588
// Get the bitmask of ready events for a file description.
593
589
let ready_events_bitmask = fd_ref. as_unix ( ) . get_epoll_ready_events ( ) ?. get_event_bitmask ( ecx) ;
594
590
let epoll_event_interest = interest. borrow ( ) ;
591
+ let epfd = epoll_event_interest. weak_epfd . upgrade ( ) . unwrap ( ) ;
595
592
// This checks if any of the events specified in epoll_event_interest.events
596
593
// match those in ready_events.
597
594
let flags = epoll_event_interest. events & ready_events_bitmask;
598
595
// If there is any event that we are interested in being specified as ready,
599
596
// insert an epoll_return to the ready list.
600
597
if flags != 0 {
601
598
let epoll_key = ( id, epoll_event_interest. fd_num ) ;
602
- let ready_list = & mut epoll_event_interest . ready_list . mapping . borrow_mut ( ) ;
599
+ let mut ready_list = epfd . ready_list . mapping . borrow_mut ( ) ;
603
600
let mut event_instance = EpollEventInstance :: new ( flags, epoll_event_interest. data ) ;
604
601
// If we are tracking data races, remember the current clock so we can sync with it later.
605
602
ecx. release_clock ( |clock| {
0 commit comments