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