1use super::fd_set::FdSet;
20use super::{
21 Duration, Errno, Result, Select, SigmaskOp, Sigset, TryInto as _, VirtualSystem, raise_sigchld,
22 signal,
23};
24use crate::job::ProcessState;
25use crate::system::FdSet as _;
26use std::cell::{Cell, LazyCell};
27use std::ffi::c_int;
28use std::future::poll_fn;
29use std::rc::Rc;
30use std::task::{Poll, Waker};
31
32impl Select for VirtualSystem {
33 type FdSet = FdSet;
34
35 fn select<'a>(
46 &self,
47 readers: &'a mut FdSet,
48 writers: &'a mut FdSet,
49 timeout: Option<Duration>,
50 signal_mask: Option<&Sigset>,
51 ) -> impl Future<Output = Result<c_int>> + use<'a> {
52 let this = self.clone();
53 let signal_mask = signal_mask.map(|mask| mask.iter().copied().collect::<Vec<_>>());
54 #[allow(clippy::await_holding_refcell_ref, reason = "false positive")]
55 async move {
56 let (old_mask, old_caught_signals, deadline) = {
57 let state = &mut *this.state.borrow_mut();
58 let proc = state
59 .processes
60 .get_mut(&this.process_id)
61 .expect("the current process should be in the system state");
62
63 let old_caught_signals = proc.caught_signals.len();
64
65 let old_mask = match signal_mask {
66 None => None,
67 Some(new_mask) => {
68 let old_mask = proc
69 .blocked_signals()
70 .iter()
71 .copied()
72 .collect::<Vec<signal::Number>>();
73
74 let result = proc.block_signals(SigmaskOp::Set, new_mask);
75 if result.process_state_changed {
76 let ppid = proc.ppid;
77 raise_sigchld(state, ppid);
78 }
79
80 Some(old_mask)
81 }
82 };
83
84 let deadline = match timeout {
85 None | Some(Duration::ZERO) => None,
87 Some(timeout) => {
88 let now = state.now;
89 let now = now.expect("the current time should be set in the system state");
90 Some(now + timeout)
91 }
92 };
93
94 (old_mask, old_caught_signals, deadline)
95 };
96
97 let waker: LazyCell<Rc<Cell<Option<Waker>>>> = LazyCell::default();
98
99 let result = poll_fn(|context| {
100 let state = &mut *this.state.borrow_mut();
101 let proc = state
102 .processes
103 .get_mut(&this.process_id)
104 .expect("the current process should be in the system state");
105
106 if let ProcessState::Halted(reason) = proc.state() {
108 if reason.is_stopped() {
109 waker.set(Some(context.waker().clone()));
110 proc.wake_on_resumption(Rc::downgrade(&waker));
111 return Poll::Pending;
112 }
113 }
114
115 if proc.caught_signals.len() != old_caught_signals {
117 return Poll::Ready(Err(Errno::EINTR));
118 }
119
120 let mut ready_readers = FdSet::new();
122 let mut ready_writers = FdSet::new();
123 for fd in readers.iter().cloned() {
124 let Some(fd_body) = proc.fds().get(&fd) else {
125 return Poll::Ready(Err(Errno::EBADF));
126 };
127 let ofd = fd_body.open_file_description.borrow();
128 if ofd.is_ready_for_reading() {
129 ready_readers.insert(fd);
130 }
131 }
132 for fd in writers.iter().cloned() {
133 let Some(fd_body) = proc.fds().get(&fd) else {
134 return Poll::Ready(Err(Errno::EBADF));
135 };
136 let ofd = fd_body.open_file_description.borrow();
137 if ofd.is_ready_for_writing() {
138 ready_writers.insert(fd);
139 }
140 }
141 let count = (ready_readers.len() + ready_writers.len())
142 .try_into()
143 .unwrap();
144 if count > 0 {
145 *readers = ready_readers;
146 *writers = ready_writers;
147 return Poll::Ready(Ok(count));
148 }
149
150 let expired = match deadline {
152 None => timeout == Some(Duration::ZERO),
153 Some(deadline) => {
154 let now = state.now;
155 let now = now.expect("the current time should be set in the system state");
156 now >= deadline
157 }
158 };
159 if expired {
160 *readers = FdSet::new();
161 *writers = FdSet::new();
162 return Poll::Ready(Ok(0));
163 }
164
165 waker.set(Some(context.waker().clone()));
167 proc.register_signal_waker(Rc::downgrade(&waker));
168 for fd in readers.iter() {
169 let mut ofd = proc.fds()[fd].open_file_description.borrow_mut();
170 ofd.register_reader_waker(Rc::downgrade(&waker));
171 }
172 for fd in writers.iter() {
173 let mut ofd = proc.fds()[fd].open_file_description.borrow_mut();
174 ofd.register_writer_waker(Rc::downgrade(&waker));
175 }
176 if let Some(deadline) = deadline {
177 state.scheduled_wakers.push(deadline, Rc::downgrade(&waker));
178 }
179 Poll::Pending
180 })
181 .await;
182
183 drop(waker);
184
185 if let Some(old_mask) = old_mask {
187 let mut state = this.state.borrow_mut();
188 let proc = state
189 .processes
190 .get_mut(&this.process_id)
191 .expect("the current process should be in the system state");
192 let result = proc.block_signals(SigmaskOp::Set, old_mask);
193 if result.process_state_changed {
194 let ppid = proc.ppid;
195 raise_sigchld(&mut state, ppid);
196 drop(state);
197 this.block_until_running().await;
198 }
199 }
200
201 result
202 }
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 use super::super::Process;
209 use super::super::{PIPE_BUF, PIPE_SIZE, SIGCHLD, SIGCONT, SIGTSTP};
210 use super::*;
211 use crate::io::Fd;
212 use crate::job::Pid;
213 use crate::system::{
214 CaughtSignals as _, Close as _, Disposition, Pipe as _, Read as _, SendSignal as _,
215 Sigaction as _, Sigmask as _, Sigset as _, Write as _,
216 };
217 use crate::test_helper::WakeFlag;
218 use futures_util::FutureExt as _;
219 use std::pin::pin;
220 use std::sync::Arc;
221 use std::task::{Context, Waker};
222 use std::time::Instant;
223
224 #[test]
225 fn select_with_no_condition_blocks_forever() {
226 let system = VirtualSystem::new();
227 let mut readers = FdSet::new();
228 let mut writers = FdSet::new();
229 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
230
231 let woken = Arc::new(WakeFlag::new());
233 let waker = Waker::from(Arc::clone(&woken));
234 let mut context = Context::from_waker(&waker);
235 let poll = select.as_mut().poll(&mut context);
236 assert_eq!(poll, Poll::Pending);
237 assert!(!woken.is_woken());
238 }
239
240 #[test]
241 fn select_with_zero_timeout_returns_immediately() {
242 let system = VirtualSystem::new();
243 let mut readers = FdSet::new();
244 let mut writers = FdSet::new();
245 let mut select =
246 pin!(system.select(&mut readers, &mut writers, Some(Duration::ZERO), None));
247
248 let woken = Arc::new(WakeFlag::new());
250 let waker = Waker::from(Arc::clone(&woken));
251 let mut context = Context::from_waker(&waker);
252 let poll = select.as_mut().poll(&mut context);
253 assert_eq!(poll, Poll::Ready(Ok(0)));
254 assert!(!woken.is_woken());
255 }
256
257 #[test]
258 fn select_regular_file_is_always_ready() {
259 let system = VirtualSystem::new();
260 let mut readers = FdSet::from_fds([Fd::STDIN]);
261 let mut writers = FdSet::from_fds([Fd::STDOUT, Fd::STDERR]);
262 {
263 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
264
265 let woken = Arc::new(WakeFlag::new());
266 let waker = Waker::from(Arc::clone(&woken));
267 let mut context = Context::from_waker(&waker);
268 let poll = select.as_mut().poll(&mut context);
269 assert_eq!(poll, Poll::Ready(Ok(3)));
270 assert!(!woken.is_woken());
271 }
272 assert_eq!(readers, FdSet::from_fds([Fd::STDIN]));
273 assert_eq!(writers, FdSet::from_fds([Fd::STDOUT, Fd::STDERR]));
274 }
275
276 #[test]
277 fn select_pipe_reader_is_ready_if_writer_is_closed() {
278 let system = VirtualSystem::new();
279 let (reader, writer) = system.pipe().unwrap();
280 system.close(writer).unwrap();
281 let mut readers = FdSet::from_fds([reader]);
282 let mut writers = FdSet::new();
283 {
284 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
285
286 let woken = Arc::new(WakeFlag::new());
287 let waker = Waker::from(Arc::clone(&woken));
288 let mut context = Context::from_waker(&waker);
289 let poll = select.as_mut().poll(&mut context);
290 assert_eq!(poll, Poll::Ready(Ok(1)));
291 assert!(!woken.is_woken());
292 }
293 assert_eq!(readers, FdSet::from_fds([reader]));
294 assert_eq!(writers, FdSet::new());
295 }
296
297 #[test]
298 fn select_pipe_reader_is_ready_if_something_has_been_written() {
299 let system = VirtualSystem::new();
300 let (reader, writer) = system.pipe().unwrap();
301 system.write(writer, &[0]).now_or_never().unwrap().unwrap();
302 let mut readers = FdSet::from_fds([reader]);
303 let mut writers = FdSet::new();
304 {
305 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
306
307 let woken = Arc::new(WakeFlag::new());
308 let waker = Waker::from(Arc::clone(&woken));
309 let mut context = Context::from_waker(&waker);
310 let poll = select.as_mut().poll(&mut context);
311 assert_eq!(poll, Poll::Ready(Ok(1)));
312 assert!(!woken.is_woken());
313 }
314 assert_eq!(readers, FdSet::from_fds([reader]));
315 assert_eq!(writers, FdSet::new());
316 }
317
318 #[test]
319 fn select_pipe_reader_gets_ready_when_some_data_is_written() {
320 let system = VirtualSystem::new();
321 let (reader, writer) = system.pipe().unwrap();
322 let mut readers = FdSet::from_fds([reader]);
323 let mut writers = FdSet::new();
324 {
325 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
326
327 let woken = Arc::new(WakeFlag::new());
330 let waker = Waker::from(Arc::clone(&woken));
331 let mut context = Context::from_waker(&waker);
332 let poll = select.as_mut().poll(&mut context);
333 assert_eq!(poll, Poll::Pending);
334 assert!(!woken.is_woken());
335
336 system.write(writer, &[0]).now_or_never().unwrap().unwrap();
338 assert!(woken.is_woken());
339
340 let woken = Arc::new(WakeFlag::new());
342 let waker = Waker::from(Arc::clone(&woken));
343 let mut context = Context::from_waker(&waker);
344 let poll = select.as_mut().poll(&mut context);
345 assert_eq!(poll, Poll::Ready(Ok(1)));
346 assert!(!woken.is_woken());
347 }
348 assert_eq!(readers, FdSet::from_fds([reader]));
349 assert_eq!(writers, FdSet::new());
350 }
351
352 #[test]
353 fn select_pipe_writer_is_ready_if_pipe_is_not_full() {
354 let system = VirtualSystem::new();
355 let (_reader, writer) = system.pipe().unwrap();
356 let mut readers = FdSet::new();
357 let mut writers = FdSet::from_fds([writer]);
358 {
359 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
360
361 let woken = Arc::new(WakeFlag::new());
362 let waker = Waker::from(Arc::clone(&woken));
363 let mut context = Context::from_waker(&waker);
364 let poll = select.as_mut().poll(&mut context);
365 assert_eq!(poll, Poll::Ready(Ok(1)));
366 assert!(!woken.is_woken());
367 }
368 assert_eq!(readers, FdSet::new());
369 assert_eq!(writers, FdSet::from_fds([writer]));
370 }
371
372 #[test]
373 fn select_pipe_writer_gets_ready_when_some_data_is_read() {
374 let system = VirtualSystem::new();
375 let (reader, writer) = system.pipe().unwrap();
376 let mut readers = FdSet::new();
377 let mut writers = FdSet::from_fds([writer]);
378
379 system
381 .write(writer, &[0; PIPE_SIZE])
382 .now_or_never()
383 .unwrap()
384 .unwrap();
385
386 {
387 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
388
389 let woken = Arc::new(WakeFlag::new());
391 let waker = Waker::from(Arc::clone(&woken));
392 let mut context = Context::from_waker(&waker);
393 let poll = select.as_mut().poll(&mut context);
394 assert_eq!(poll, Poll::Pending);
395 assert!(!woken.is_woken());
396
397 system
399 .read(reader, &mut [0; PIPE_BUF])
400 .now_or_never()
401 .unwrap()
402 .unwrap();
403 assert!(woken.is_woken());
404
405 let woken = Arc::new(WakeFlag::new());
407 let waker = Waker::from(Arc::clone(&woken));
408 let mut context = Context::from_waker(&waker);
409 let poll = select.as_mut().poll(&mut context);
410 assert_eq!(poll, Poll::Ready(Ok(1)));
411 assert!(!woken.is_woken());
412 }
413 assert_eq!(readers, FdSet::new());
414 assert_eq!(writers, FdSet::from_fds([writer]));
415 }
416
417 #[test]
418 fn select_on_unreadable_fd() {
419 let system = VirtualSystem::new();
420 let (_reader, writer) = system.pipe().unwrap();
421 let mut fds = FdSet::from_fds([writer]);
422 let result = system
423 .select(&mut fds, &mut FdSet::new(), None, None)
424 .now_or_never()
425 .unwrap();
426 assert_eq!(result, Ok(1));
427 assert_eq!(fds, FdSet::from_fds([writer]));
428 }
429
430 #[test]
431 fn select_on_unwritable_fd() {
432 let system = VirtualSystem::new();
433 let (reader, _writer) = system.pipe().unwrap();
434 let mut fds = FdSet::from_fds([reader]);
435 let result = system
436 .select(&mut FdSet::new(), &mut fds, None, None)
437 .now_or_never()
438 .unwrap();
439 assert_eq!(result, Ok(1));
440 assert_eq!(fds, FdSet::from_fds([reader]));
441 }
442
443 #[test]
444 fn select_on_invalid_fd_for_readers() {
445 let system = VirtualSystem::new();
446 let mut readers = FdSet::from_fds([Fd(17)]);
447 let mut writers = FdSet::new();
448 {
449 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
450
451 let woken = Arc::new(WakeFlag::new());
452 let waker = Waker::from(Arc::clone(&woken));
453 let mut context = Context::from_waker(&waker);
454 let poll = select.as_mut().poll(&mut context);
455 assert_eq!(poll, Poll::Ready(Err(Errno::EBADF)));
456 assert!(!woken.is_woken());
457 }
458 assert_eq!(readers, FdSet::from_fds([Fd(17)]));
459 assert_eq!(writers, FdSet::new());
460 }
461
462 #[test]
463 fn select_on_invalid_fd_for_writers() {
464 let system = VirtualSystem::new();
465 let mut readers = FdSet::new();
466 let mut writers = FdSet::from_fds([Fd(17)]);
467 {
468 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
469
470 let woken = Arc::new(WakeFlag::new());
471 let waker = Waker::from(Arc::clone(&woken));
472 let mut context = Context::from_waker(&waker);
473 let poll = select.as_mut().poll(&mut context);
474 assert_eq!(poll, Poll::Ready(Err(Errno::EBADF)));
475 assert!(!woken.is_woken());
476 }
477 assert_eq!(readers, FdSet::new());
478 assert_eq!(writers, FdSet::from_fds([Fd(17)]));
479 }
480
481 fn system_for_catching_sigchld() -> VirtualSystem {
482 let system = VirtualSystem::new();
483 system
484 .sigmask(Some((SigmaskOp::Add, &Sigset::from(SIGCHLD))), None)
485 .now_or_never()
486 .unwrap()
487 .unwrap();
488 system.sigaction(SIGCHLD, Disposition::Catch).unwrap();
489 system
490 }
491
492 #[test]
493 fn select_on_pending_signal() {
494 let system = system_for_catching_sigchld();
495 let _ = system.current_process_mut().raise_signal(SIGCHLD);
496 let mut readers = FdSet::new();
497 let mut writers = FdSet::new();
498
499 let mut select =
500 pin!(system.select(&mut readers, &mut writers, None, Some(&Sigset::new())));
501
502 let woken = Arc::new(WakeFlag::new());
503 let waker = Waker::from(Arc::clone(&woken));
504 let mut context = Context::from_waker(&waker);
505 let poll = select.as_mut().poll(&mut context);
506 assert_eq!(poll, Poll::Ready(Err(Errno::EINTR)));
507 assert!(!woken.is_woken());
508 assert_eq!(system.caught_signals(), [SIGCHLD]);
509 let mut mask = Sigset::new();
511 system
512 .sigmask(None, Some(&mut mask))
513 .now_or_never()
514 .unwrap()
515 .unwrap();
516 assert_eq!(mask, Sigset::from(SIGCHLD));
517 }
518
519 #[test]
520 fn select_interrupted_by_signal() {
521 let system = VirtualSystem::new();
522 system.sigaction(SIGCHLD, Disposition::Catch).unwrap();
523 let mut readers = FdSet::new();
524 let mut writers = FdSet::new();
525
526 let mut select = pin!(system.select(&mut readers, &mut writers, None, None));
527
528 let woken = Arc::new(WakeFlag::new());
530 let waker = Waker::from(Arc::clone(&woken));
531 let mut context = Context::from_waker(&waker);
532 let poll = select.as_mut().poll(&mut context);
533 assert_eq!(poll, Poll::Pending);
534 assert!(!woken.is_woken());
535
536 let woken = Arc::new(WakeFlag::new());
539 let waker = Waker::from(Arc::clone(&woken));
540 let mut context = Context::from_waker(&waker);
541 let poll = select.as_mut().poll(&mut context);
542 assert_eq!(poll, Poll::Pending);
543 assert!(!woken.is_woken());
544
545 _ = system.current_process_mut().raise_signal(SIGCHLD);
547 assert!(woken.is_woken());
548
549 let woken = Arc::new(WakeFlag::new());
551 let waker = Waker::from(Arc::clone(&woken));
552 let mut context = Context::from_waker(&waker);
553 let poll = select.as_mut().poll(&mut context);
554 assert_eq!(poll, Poll::Ready(Err(Errno::EINTR)));
555 assert!(!woken.is_woken());
556 }
557
558 #[test]
559 fn select_on_signal_delivered_while_waiting() {
560 let system = system_for_catching_sigchld();
561 let mut readers = FdSet::new();
562 let mut writers = FdSet::new();
563
564 let mut select =
565 pin!(system.select(&mut readers, &mut writers, None, Some(&Sigset::new())));
566
567 let woken = Arc::new(WakeFlag::new());
569 let waker = Waker::from(Arc::clone(&woken));
570 let mut context = Context::from_waker(&waker);
571 let poll = select.as_mut().poll(&mut context);
572 assert_eq!(poll, Poll::Pending);
573 assert!(!woken.is_woken());
574 let mut mask = Sigset::new();
576 system
577 .sigmask(None, Some(&mut mask))
578 .now_or_never()
579 .unwrap()
580 .unwrap();
581 assert_eq!(mask, Sigset::new());
582
583 let woken = Arc::new(WakeFlag::new());
586 let waker = Waker::from(Arc::clone(&woken));
587 let mut context = Context::from_waker(&waker);
588 let poll = select.as_mut().poll(&mut context);
589 assert_eq!(poll, Poll::Pending);
590 assert!(!woken.is_woken());
591
592 let _ = system.current_process_mut().raise_signal(SIGCHLD);
594 assert!(woken.is_woken());
595
596 let woken = Arc::new(WakeFlag::new());
598 let waker = Waker::from(Arc::clone(&woken));
599 let mut context = Context::from_waker(&waker);
600 let poll = select.as_mut().poll(&mut context);
601 assert_eq!(poll, Poll::Ready(Err(Errno::EINTR)));
602 assert!(!woken.is_woken());
603 assert_eq!(system.caught_signals(), [SIGCHLD]);
604 let mut mask = Sigset::new();
606 system
607 .sigmask(None, Some(&mut mask))
608 .now_or_never()
609 .unwrap()
610 .unwrap();
611 assert_eq!(mask, Sigset::from(SIGCHLD));
612 }
613
614 #[test]
615 fn select_timeout() {
616 let system = VirtualSystem::new();
617 let now = Instant::now();
618 system.state.borrow_mut().now = Some(now);
619
620 let (reader_1, _writer_1) = system.pipe().unwrap();
622 let (_reader_2, writer_2) = system.pipe().unwrap();
624 system
625 .write(writer_2, &[0; PIPE_SIZE])
626 .now_or_never()
627 .unwrap()
628 .unwrap();
629 let mut readers = FdSet::from_fds([reader_1]);
630 let mut writers = FdSet::from_fds([writer_2]);
631 let timeout = Duration::new(42, 195);
632
633 {
634 let mut select = pin!(system.select(&mut readers, &mut writers, Some(timeout), None));
635
636 let woken = Arc::new(WakeFlag::new());
639 let waker = Waker::from(Arc::clone(&woken));
640 let mut context = Context::from_waker(&waker);
641 let poll = select.as_mut().poll(&mut context);
642 assert_eq!(poll, Poll::Pending);
643 assert!(!woken.is_woken());
644
645 let time_before_timeout = now + Duration::new(42, 0);
647 system.state.borrow_mut().advance_time(time_before_timeout);
648 assert!(!woken.is_woken());
649
650 let woken = Arc::new(WakeFlag::new());
653 let waker = Waker::from(Arc::clone(&woken));
654 let mut context = Context::from_waker(&waker);
655 let poll = select.as_mut().poll(&mut context);
656 assert_eq!(poll, Poll::Pending);
657 assert!(!woken.is_woken());
658
659 system.state.borrow_mut().advance_time(now + timeout);
662 assert!(woken.is_woken());
663
664 let woken = Arc::new(WakeFlag::new());
666 let waker = Waker::from(Arc::clone(&woken));
667 let mut context = Context::from_waker(&waker);
668 let poll = select.as_mut().poll(&mut context);
669 assert_eq!(poll, Poll::Ready(Ok(0)));
670 }
671 assert_eq!(readers, FdSet::new());
673 assert_eq!(writers, FdSet::new());
674 }
675
676 fn virtual_system_with_parent_process() -> VirtualSystem {
677 let system = VirtualSystem::new();
678 let ppid = system.current_process().ppid;
679 let mut parent = Process::with_parent_and_group(Pid(1), Pid(1));
680 parent.set_disposition(SIGCHLD, Disposition::Catch);
681 system.state.borrow_mut().processes.insert(ppid, parent);
682 system
683 }
684
685 #[test]
690 fn select_returns_pending_while_process_is_suspended_1() {
691 let system = virtual_system_with_parent_process();
692 let now = Instant::now();
693 system.state.borrow_mut().now = Some(now);
694 system
695 .sigmask(Some((SigmaskOp::Add, &Sigset::from(SIGTSTP))), None)
696 .now_or_never()
697 .unwrap()
698 .unwrap();
699
700 system.raise(SIGTSTP).now_or_never().unwrap().unwrap();
702
703 let mut readers = FdSet::new();
704 let mut writers = FdSet::new();
705
706 let mut select = pin!(system.select(
707 &mut readers,
708 &mut writers,
709 Some(Duration::from_secs(1)),
710 Some(&Sigset::new())
711 ));
712
713 let woken = Arc::new(WakeFlag::new());
714 let waker = Waker::from(Arc::clone(&woken));
715 let mut context = Context::from_waker(&waker);
716 let poll = select.as_mut().poll(&mut context);
717 assert_eq!(poll, Poll::Pending);
718 assert!(!woken.is_woken());
719
720 {
723 let state = system.state.borrow();
724 let ppid = state.processes[&system.process_id].ppid;
725 assert_eq!(state.processes[&ppid].caught_signals, [SIGCHLD]);
726 }
727
728 system
730 .state
731 .borrow_mut()
732 .advance_time(now + Duration::from_secs(2));
733 let woken = Arc::new(WakeFlag::new());
734 let waker = Waker::from(Arc::clone(&woken));
735 let mut context = Context::from_waker(&waker);
736 let poll = select.as_mut().poll(&mut context);
737 assert_eq!(poll, Poll::Pending);
738 assert!(!woken.is_woken());
739
740 system.raise(SIGCONT).now_or_never().unwrap().unwrap();
742 assert!(woken.is_woken());
743
744 let woken = Arc::new(WakeFlag::new());
746 let waker = Waker::from(Arc::clone(&woken));
747 let mut context = Context::from_waker(&waker);
748 let poll = select.as_mut().poll(&mut context);
749 assert_eq!(poll, Poll::Ready(Ok(0)));
750 }
751
752 #[test]
758 fn select_returns_pending_while_process_is_suspended_2() {
759 let system = virtual_system_with_parent_process();
760 let now = Instant::now();
761 system.state.borrow_mut().now = Some(now);
762
763 let mut readers = FdSet::new();
764 let mut writers = FdSet::new();
765
766 let mut select = pin!(system.select(
767 &mut readers,
768 &mut writers,
769 Some(Duration::from_secs(1)),
770 Some(&Sigset::from(SIGTSTP))
771 ));
772
773 let woken = Arc::new(WakeFlag::new());
775 let waker = Waker::from(Arc::clone(&woken));
776 let mut context = Context::from_waker(&waker);
777 let poll = select.as_mut().poll(&mut context);
778 assert_eq!(poll, Poll::Pending);
779 assert!(!woken.is_woken());
780
781 let mut mask = Sigset::new();
783 system
784 .sigmask(None, Some(&mut mask))
785 .now_or_never()
786 .unwrap()
787 .unwrap();
788 assert_eq!(mask, Sigset::from(SIGTSTP));
789
790 system.raise(SIGTSTP).now_or_never().unwrap().unwrap();
792 assert!(!woken.is_woken());
793
794 let woken = Arc::new(WakeFlag::new());
796 let waker = Waker::from(Arc::clone(&woken));
797 let mut context = Context::from_waker(&waker);
798 let poll = select.as_mut().poll(&mut context);
799 assert_eq!(poll, Poll::Pending);
800 assert!(!woken.is_woken());
801
802 system
804 .state
805 .borrow_mut()
806 .advance_time(now + Duration::from_secs(1));
807 assert!(woken.is_woken());
808
809 let woken = Arc::new(WakeFlag::new());
812 let waker = Waker::from(Arc::clone(&woken));
813 let mut context = Context::from_waker(&waker);
814 let poll = select.as_mut().poll(&mut context);
815 assert_eq!(poll, Poll::Pending);
816 assert!(!woken.is_woken());
817
818 {
820 let state = system.state.borrow();
821 let ppid = state.processes[&system.process_id].ppid;
822 assert_eq!(state.processes[&ppid].caught_signals, [SIGCHLD]);
823 }
824
825 system.raise(SIGCONT).now_or_never().unwrap().unwrap();
827 assert!(woken.is_woken());
828
829 let woken = Arc::new(WakeFlag::new());
831 let waker = Waker::from(Arc::clone(&woken));
832 let mut context = Context::from_waker(&waker);
833 let poll = select.as_mut().poll(&mut context);
834 assert_eq!(poll, Poll::Ready(Ok(0)));
835 }
836}