@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
33use std:: io;
44use std:: rc:: { Rc , Weak } ;
55
6- use crate :: shims:: unix:: fd:: FdId ;
6+ use crate :: shims:: unix:: fd:: { FdId , FileDescriptionRef } ;
77use crate :: shims:: unix:: * ;
88use crate :: * ;
99
@@ -153,6 +153,60 @@ impl EpollInterestTable {
153153 }
154154}
155155
156+ impl < ' tcx > EvalContextExtPriv < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
157+ trait EvalContextExtPriv < ' tcx > : crate :: MiriInterpCxExt < ' tcx > {
158+ /// For a specific unique file descriptor id, get its ready events and update
159+ /// the corresponding ready list. This function is called whenever a file description
160+ /// is registered with epoll, or when read, write, or close operations are performed,
161+ /// regardless of any changes in readiness.
162+ ///
163+ /// This is an internal helper function and is typically not meant to be used directly.
164+ /// `FileDescriptionRef::check_and_update_readiness` should be preferred.
165+ fn check_and_update_readiness (
166+ & self ,
167+ id : FdId ,
168+ get_ready_events : impl FnOnce ( ) -> InterpResult < ' tcx , EpollReadyEvents > ,
169+ ) -> InterpResult < ' tcx , ( ) > {
170+ let this = self . eval_context_ref ( ) ;
171+ // Get a list of EpollEventInterest that is associated to a specific file description.
172+ if let Some ( epoll_interests) = this. machine . epoll_interests . get_epoll_interest ( id) {
173+ let epoll_ready_events = get_ready_events ( ) ?;
174+ // Get the bitmask of ready events.
175+ let ready_events = epoll_ready_events. get_event_bitmask ( this) ;
176+
177+ for weak_epoll_interest in epoll_interests {
178+ if let Some ( epoll_interest) = weak_epoll_interest. upgrade ( ) {
179+ // This checks if any of the events specified in epoll_event_interest.events
180+ // match those in ready_events.
181+ let epoll_event_interest = epoll_interest. borrow ( ) ;
182+ let flags = epoll_event_interest. events & ready_events;
183+ // If there is any event that we are interested in being specified as ready,
184+ // insert an epoll_return to the ready list.
185+ if flags != 0 {
186+ let epoll_key = ( id, epoll_event_interest. file_descriptor ) ;
187+ let ready_list = & mut epoll_event_interest. ready_list . borrow_mut ( ) ;
188+ let event_instance =
189+ EpollEventInstance :: new ( flags, epoll_event_interest. data ) ;
190+ ready_list. insert ( epoll_key, event_instance) ;
191+ }
192+ }
193+ }
194+ }
195+ Ok ( ( ) )
196+ }
197+ }
198+
199+ impl FileDescriptionRef {
200+ /// Function used to retrieve the readiness events of a file description and insert
201+ /// an `EpollEventInstance` into the ready list if the file description is ready.
202+ pub ( crate ) fn check_and_update_readiness < ' tcx > (
203+ & self ,
204+ ecx : & mut InterpCx < ' tcx , MiriMachine < ' tcx > > ,
205+ ) -> InterpResult < ' tcx , ( ) > {
206+ ecx. check_and_update_readiness ( self . get_id ( ) , || self . get_epoll_ready_events ( ) )
207+ }
208+ }
209+
156210impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
157211pub trait EvalContextExt < ' tcx > : crate :: MiriInterpCxExt < ' tcx > {
158212 /// This function returns a file descriptor referring to the new `Epoll` instance. This file
@@ -431,44 +485,4 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
431485 }
432486 Ok ( Scalar :: from_i32 ( num_of_events) )
433487 }
434-
435- /// For a specific unique file descriptor id, get its ready events and update
436- /// the corresponding ready list. This function is called whenever a file description
437- /// is registered with epoll, or when read, write, or close operations are performed,
438- /// regardless of any changes in readiness.
439- ///
440- /// This is an internal helper function and is typically not meant to be used directly.
441- /// In most cases, `FileDescriptionRef::check_and_update_readiness` should be preferred.
442- fn check_and_update_readiness (
443- & self ,
444- id : FdId ,
445- get_ready_events : impl FnOnce ( ) -> InterpResult < ' tcx , EpollReadyEvents > ,
446- ) -> InterpResult < ' tcx , ( ) > {
447- let this = self . eval_context_ref ( ) ;
448- // Get a list of EpollEventInterest that is associated to a specific file description.
449- if let Some ( epoll_interests) = this. machine . epoll_interests . get_epoll_interest ( id) {
450- let epoll_ready_events = get_ready_events ( ) ?;
451- // Get the bitmask of ready events.
452- let ready_events = epoll_ready_events. get_event_bitmask ( this) ;
453-
454- for weak_epoll_interest in epoll_interests {
455- if let Some ( epoll_interest) = weak_epoll_interest. upgrade ( ) {
456- // This checks if any of the events specified in epoll_event_interest.events
457- // match those in ready_events.
458- let epoll_event_interest = epoll_interest. borrow ( ) ;
459- let flags = epoll_event_interest. events & ready_events;
460- // If there is any event that we are interested in being specified as ready,
461- // insert an epoll_return to the ready list.
462- if flags != 0 {
463- let epoll_key = ( id, epoll_event_interest. file_descriptor ) ;
464- let ready_list = & mut epoll_event_interest. ready_list . borrow_mut ( ) ;
465- let event_instance =
466- EpollEventInstance :: new ( flags, epoll_event_interest. data ) ;
467- ready_list. insert ( epoll_key, event_instance) ;
468- }
469- }
470- }
471- }
472- Ok ( ( ) )
473- }
474488}
0 commit comments