/// Blocking wait on all waited upon events with a timeout.
Blocking wait on all waited upon events with a timeout.
Blocking wait on all waited upon events with a timeout .
pub fn wait(
        &self,
        current_task: &Task,
        max_events: i32,
        timeout: i32,
    ) -> Result<Vec<EpollEvent>, Errno> {
        // First we start waiting again on wait objects that have
        // previously been triggered.
        {
            let mut rearm_list = self.rearm_list.lock();
            let waits = self.wait_objects.write();
            for to_wait in rearm_list.iter() {
                // TODO handle interrupts here
                let w = waits.get(&to_wait.key).ok_or(errno!(EFAULT))?;
                self.wait_on_file(to_wait.key, w)?;
            }
            rearm_list.clear();
        }
        let mut wait_deadline = if timeout == -1 {
            zx::Time::INFINITE
        } else if timeout >= 0 {
            let millis = timeout as i64;
            zx::Time::after(zx::Duration::from_millis(millis))
        } else {
            return error!(EINVAL);
        };
        // The handlers in the waits cause items to be appended
        // to trigger_list. See the closure in `wait_on_file` to see
        // how this happens.
        let mut pending_list: Vec<ReadyObject> = vec![];
        loop {
            match self.waiter.wait_until(current_task, wait_deadline) {
                Ok(_) => {}
                Err(err) => {
                    if err == ETIMEDOUT {
                        break;
                    }
                    return error!(err);
                }
            }
            // For each sucessful wait, we take an item off
            // the trigger list and store it locally. This allows
            // multiple threads to call EpollFileObject::wait
            // simultaneously.  We break early if the max_events
            // is reached, leaving items on the trigger list for
            //the next wait.
            let mut trigger_list = self.trigger_list.lock();
            if let Some(pending) = trigger_list.pop_front() {
                pending_list.push(pending);
                if pending_list.len() == max_events as usize {
                    break;
                }
            }
            wait_deadline = zx::Time::ZERO;
        }
        // Process the pening list and add processed ReadyObject
        // enties to the rearm_list for the next wait.
        let mut result = vec![];
        let mut rearm_list = self.rearm_list.lock();
        let wait_objects = self.wait_objects.read();
        for pending_event in pending_list.iter() {
            // The wait could have been deleted by here,
            // so ignore the None case.
            if let Some(wait) = wait_objects.get(&pending_event.key) {
                result.push(EpollEvent { events: pending_event.observed.mask(), data: wait.data });
                // TODO When edge-triggered epoll, EPOLLET, is
                // implemented, we would enable to wait here,
                // instead of adding it to the rearm list.
                rearm_list.push(pending_event.clone());
            }
        }
        Ok(result)
    }
pub fn wait ( & self , current_task : & Task , max_events : i32 , timeout : i32 , ) -> Result < Vec < EpollEvent > , Errno > { // First we start waiting again on wait objects that have // previously been triggered. { let mut rearm_list = self . rearm_list . lock ( ) ; let waits = self . wait_objects . write ( ) ; for to_wait in rearm_list . iter ( ) { // TODO handle interrupts here let w = waits . get ( & to_wait . key ) . ok_or ( errno ! ( EFAULT ) ) ? ; self . wait_on_file ( to_wait . key , w ) ? ; } rearm_list . clear ( ) ; } let mut wait_deadline = if timeout == - 1 { zx :: Time :: INFINITE } else if timeout >= 0 { let millis = timeout as i64 ; zx :: Time :: after ( zx :: Duration :: from_millis ( millis ) ) } else { return error ! ( EINVAL ) ; } ; // The handlers in the waits cause items to be appended // to trigger_list. See the closure in `wait_on_file` to see // how this happens. let mut pending_list : Vec < ReadyObject > = vec ! [ ] ; loop { match self . waiter . wait_until ( current_task , wait_deadline ) { Ok ( _ ) => { } Err ( err ) => { if err == ETIMEDOUT { break ; } return error ! ( err ) ; } } // For each sucessful wait, we take an item off // the trigger list and store it locally. This allows // multiple threads to call EpollFileObject::wait // simultaneously.  We break early if the max_events // is reached, leaving items on the trigger list for //the next wait. let mut trigger_list = self . trigger_list . lock ( ) ; if let Some ( pending ) = trigger_list . pop_front ( ) { pending_list . push ( pending ) ; if pending_list . len ( ) == max_events as usize { break ; } } wait_deadline = zx :: Time :: ZERO ; } // Process the pening list and add processed ReadyObject // enties to the rearm_list for the next wait. let mut result = vec ! [ ] ; let mut rearm_list = self . rearm_list . lock ( ) ; let wait_objects = self . wait_objects . read ( ) ; for pending_event in pending_list . iter ( ) { // The wait could have been deleted by here, // so ignore the None case. if let Some ( wait ) = wait_objects . get ( & pending_event . key ) { result . push ( EpollEvent { events : pending_event . observed . mask ( ) , data : wait . data } ) ; // TODO When edge-triggered epoll, EPOLLET, is // implemented, we would enable to wait here, // instead of adding it to the rearm list. rearm_list . push ( pending_event . clone ( ) ) ; } } Ok ( result ) }
Blocking wait on all waited upon events with a timeout.
Blocking wait on all waited upon events with a timeout .
&self
current_task
&Task
max_events
i32
timeout
i32