1use super::super::FileType;
20use super::Inode;
21use super::WakerSet;
22use crate::path::PathBuf;
23use crate::str::UnixStr;
24use crate::system::Errno;
25use std::cell::{Cell, RefCell};
26use std::collections::HashMap;
27use std::collections::VecDeque;
28use std::rc::Rc;
29use std::rc::Weak;
30use std::task::Poll::{Pending, Ready};
31use std::task::{Poll, Waker};
32
33pub const PIPE_BUF: usize = 512;
38
39pub const PIPE_SIZE: usize = PIPE_BUF * 2;
44
45#[derive(Clone, derive_more::Debug, derive_more::Eq, derive_more::PartialEq)]
47#[non_exhaustive]
48pub enum FileBody {
49 Regular {
51 content: Vec<u8>,
53 is_native_executable: bool,
55 },
56 Directory {
58 files: HashMap<Rc<UnixStr>, Rc<RefCell<Inode>>>,
63 },
66 Fifo {
68 content: VecDeque<u8>,
70 readers: usize,
72 writers: usize,
74 #[eq(ignore)]
82 #[partial_eq(ignore)]
83 pending_open_wakers: WakerSet,
84 pending_read_wakers: WakerSet,
91 pending_write_wakers: WakerSet,
98 },
99 Symlink {
101 target: PathBuf,
103 },
104 Terminal {
108 content: Vec<u8>,
110 },
111 }
113
114impl Default for FileBody {
116 fn default() -> Self {
117 FileBody::Regular {
118 content: Vec::default(),
119 is_native_executable: bool::default(),
120 }
121 }
122}
123
124impl FileBody {
125 #[must_use]
127 pub fn new<T: Into<Vec<u8>>>(bytes: T) -> Self {
128 FileBody::Regular {
129 content: bytes.into(),
130 is_native_executable: false,
131 }
132 }
133
134 #[must_use]
136 pub const fn r#type(&self) -> FileType {
137 match self {
138 Self::Regular { .. } => FileType::Regular,
139 Self::Directory { .. } => FileType::Directory,
140 Self::Fifo { .. } => FileType::Fifo,
141 Self::Symlink { .. } => FileType::Symlink,
142 Self::Terminal { .. } => FileType::CharacterDevice,
143 }
144 }
145
146 #[must_use]
148 pub fn size(&self) -> usize {
149 match self {
150 Self::Regular { content, .. } => content.len(),
151 Self::Directory { files } => files.len(),
152 Self::Fifo { content, .. } => content.len(),
153 Self::Symlink { target } => target.as_unix_str().len(),
154 Self::Terminal { .. } => 0,
155 }
156 }
157
158 pub(super) fn open(&mut self, is_readable: bool, is_writable: bool) {
161 if let Self::Fifo {
162 readers,
163 writers,
164 pending_open_wakers,
165 ..
166 } = self
167 {
168 if is_readable {
169 *readers += 1;
170 }
171 if is_writable {
172 *writers += 1;
173 }
174 pending_open_wakers.wake_all();
175 }
176 }
177
178 pub(super) fn close(&mut self, is_readable: bool, is_writable: bool) {
181 if let Self::Fifo {
182 readers,
183 writers,
184 pending_read_wakers,
185 pending_write_wakers,
186 ..
187 } = self
188 {
189 if is_readable {
190 *readers -= 1;
191 }
192 if is_writable {
193 *writers -= 1;
194 }
195 if *readers == 0 || *writers == 0 {
196 pending_read_wakers.wake_all();
200 pending_write_wakers.wake_all();
201 }
202 }
203 }
204
205 #[must_use]
207 pub fn is_seekable(&self) -> bool {
208 match self {
209 Self::Regular { .. } => true,
210 Self::Directory { .. } => false,
211 Self::Fifo { .. } => false,
212 Self::Symlink { .. } => false,
213 Self::Terminal { .. } => false,
214 }
215 }
216
217 #[must_use]
219 pub(super) fn is_ready_for_reading(&self) -> bool {
220 match self {
221 Self::Regular { .. }
222 | Self::Directory { .. }
223 | Self::Terminal { .. }
224 | Self::Symlink { .. } => true,
225 Self::Fifo {
226 content, writers, ..
227 } => *writers == 0 || !content.is_empty(),
228 }
229 }
230
231 #[must_use]
233 pub(super) fn is_ready_for_writing(&self) -> bool {
234 match self {
235 Self::Regular { .. }
236 | Self::Directory { .. }
237 | Self::Terminal { .. }
238 | Self::Symlink { .. } => true,
239
240 Self::Fifo {
245 content, readers, ..
246 } => *readers == 0 || PIPE_SIZE - content.len() >= PIPE_BUF,
247 }
248 }
249
250 pub(super) fn register_reader_waker(&mut self, waker: Weak<Cell<Option<Waker>>>) {
252 if let Self::Fifo {
253 pending_read_wakers,
254 ..
255 } = self
256 {
257 pending_read_wakers.insert(waker);
258 }
259 }
260
261 pub(super) fn register_writer_waker(&mut self, waker: Weak<Cell<Option<Waker>>>) {
263 if let Self::Fifo {
264 pending_write_wakers,
265 ..
266 } = self
267 {
268 pending_write_wakers.insert(waker);
269 }
270 }
271
272 pub(super) fn poll_read<F>(
298 &mut self,
299 mut buffer: &mut [u8],
300 offset: usize,
301 mut get_waker: F,
302 ) -> Poll<Result<usize, Errno>>
303 where
304 F: FnMut() -> Weak<Cell<Option<Waker>>>,
305 {
306 match self {
307 FileBody::Regular { content, .. } | FileBody::Terminal { content } => {
308 let len = content.len();
309 if offset >= len {
310 return Ready(Ok(0));
311 }
312 let limit = len - offset;
313 if buffer.len() > limit {
314 buffer = &mut buffer[..limit];
315 }
316 let count = buffer.len();
317 let src = &content[offset..][..count];
318 buffer.copy_from_slice(src);
319 Ready(Ok(count))
320 }
321
322 FileBody::Fifo {
323 content,
324 writers,
325 pending_read_wakers,
326 pending_write_wakers,
327 ..
328 } => {
329 if buffer.is_empty() {
330 return Ready(Ok(0));
331 }
332
333 let limit = content.len();
334 if limit == 0 && *writers > 0 {
335 pending_read_wakers.insert(get_waker());
337 return Pending;
338 }
339
340 let mut count = 0;
341 for to in buffer {
342 if let Some(from) = content.pop_front() {
343 *to = from;
344 count += 1;
345 } else {
346 break;
347 }
348 }
349 pending_write_wakers.wake_all();
350 Ready(Ok(count))
351 }
352
353 FileBody::Directory { .. } => Ready(Err(Errno::EISDIR)),
354
355 FileBody::Symlink { target: _ } => Ready(Err(Errno::ENOTSUP)),
356 }
357 }
358
359 pub(super) fn poll_write<F>(
391 &mut self,
392 mut buffer: &[u8],
393 offset: usize,
394 mut get_waker: F,
395 ) -> Poll<Result<usize, Errno>>
396 where
397 F: FnMut() -> Weak<Cell<Option<Waker>>>,
398 {
399 match self {
400 FileBody::Regular { content, .. } | FileBody::Terminal { content } => {
401 let len = content.len();
402 let count = buffer.len();
403 if offset > len {
404 let zeroes = offset - len;
405 content.reserve(zeroes + count);
406 content.resize_with(offset, u8::default);
407 }
408 let limit = count.min(content.len() - offset);
409 let dst = &mut content[offset..][..limit];
410 dst.copy_from_slice(&buffer[..limit]);
411 content.reserve(count - limit);
412 content.extend(&buffer[limit..]);
413 Ready(Ok(count))
414 }
415
416 FileBody::Fifo {
417 content,
418 readers,
419 pending_read_wakers,
420 pending_write_wakers,
421 ..
422 } => {
423 if *readers == 0 {
424 return Ready(Err(Errno::EPIPE));
426 }
427 let room = PIPE_SIZE - content.len();
428 if room < buffer.len() {
429 if room == 0 || buffer.len() <= PIPE_BUF {
430 pending_write_wakers.insert(get_waker());
432 return Pending;
433 }
434 buffer = &buffer[..room];
435 }
436 content.reserve_exact(room);
437 content.extend(buffer);
438 debug_assert!(content.len() <= PIPE_SIZE);
439 pending_read_wakers.wake_all();
440 Ready(Ok(buffer.len()))
441 }
442
443 FileBody::Directory { .. } => Ready(Err(Errno::EISDIR)),
444
445 FileBody::Symlink { target: _ } => Ready(Err(Errno::ENOTSUP)),
446 }
447 }
448}
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453 use crate::test_helper::WakeFlag;
454 use assert_matches::assert_matches;
455 use std::sync::Arc;
456
457 #[test]
458 fn fifo_file_body_open_increments_readers_and_writers() {
459 let mut body = FileBody::Fifo {
460 content: VecDeque::new(),
461 readers: 0,
462 writers: 0,
463 pending_open_wakers: WakerSet::new(),
464 pending_read_wakers: WakerSet::new(),
465 pending_write_wakers: WakerSet::new(),
466 };
467
468 body.open(true, false);
469 assert_matches!(
470 &body,
471 FileBody::Fifo { readers, writers, .. } if *readers == 1 && *writers == 0
472 );
473
474 body.open(false, true);
475 assert_matches!(
476 &body,
477 FileBody::Fifo { readers, writers, .. } if *readers == 1 && *writers == 1
478 );
479
480 body.open(true, true);
481 assert_matches!(
482 &body,
483 FileBody::Fifo { readers, writers, .. } if *readers == 2 && *writers == 2
484 );
485 }
486
487 #[test]
488 fn fifo_file_body_open_wakes_pending_open_wakers() {
489 let wake_flag_1 = Arc::new(WakeFlag::new());
490 let wake_flag_2 = Arc::new(WakeFlag::new());
491 let waker_1 = Rc::new(Cell::new(Some(Waker::from(wake_flag_1.clone()))));
492 let waker_2 = Rc::new(Cell::new(Some(Waker::from(wake_flag_2.clone()))));
493 let mut body = FileBody::Fifo {
494 content: VecDeque::new(),
495 readers: 0,
496 writers: 0,
497 pending_open_wakers: WakerSet::from_iter([
498 Rc::downgrade(&waker_1),
499 Rc::downgrade(&waker_2),
500 ]),
501 pending_read_wakers: WakerSet::new(),
502 pending_write_wakers: WakerSet::new(),
503 };
504 body.open(true, false);
505 assert!(wake_flag_1.is_woken());
506 assert!(wake_flag_2.is_woken());
507 assert_matches!(
508 &body,
509 FileBody::Fifo { pending_open_wakers, .. } if pending_open_wakers.is_empty()
510 );
511 }
512
513 #[test]
514 fn fifo_file_body_close_decrements_readers_and_writers() {
515 let mut body = FileBody::Fifo {
516 content: VecDeque::new(),
517 readers: 2,
518 writers: 2,
519 pending_open_wakers: WakerSet::new(),
520 pending_read_wakers: WakerSet::new(),
521 pending_write_wakers: WakerSet::new(),
522 };
523
524 body.close(true, false);
525 assert_matches!(
526 &body,
527 FileBody::Fifo { readers, writers, .. } if *readers == 1 && *writers == 2
528 );
529
530 body.close(false, true);
531 assert_matches!(
532 &body,
533 FileBody::Fifo { readers, writers, .. } if *readers == 1 && *writers == 1
534 );
535
536 body.close(true, true);
537 assert_matches!(
538 &body,
539 FileBody::Fifo { readers, writers, .. } if *readers == 0 && *writers == 0
540 );
541 }
542
543 #[test]
544 fn fifo_file_body_wakes_pending_wakers_if_no_writers_remain() {
545 let wake_flag_1 = Arc::new(WakeFlag::new());
546 let wake_flag_2 = Arc::new(WakeFlag::new());
547 let waker_1 = Rc::new(Cell::new(Some(Waker::from(wake_flag_1.clone()))));
548 let waker_2 = Rc::new(Cell::new(Some(Waker::from(wake_flag_2.clone()))));
549 let mut body = FileBody::Fifo {
550 content: VecDeque::new(),
551 readers: 1,
552 writers: 2,
553 pending_open_wakers: WakerSet::new(),
554 pending_read_wakers: WakerSet::from_iter([Rc::downgrade(&waker_1)]),
555 pending_write_wakers: WakerSet::from_iter([Rc::downgrade(&waker_2)]),
556 };
557
558 body.close(false, true);
561 assert!(!wake_flag_1.is_woken());
562 assert!(!wake_flag_2.is_woken());
563
564 body.close(false, true);
566 assert!(wake_flag_1.is_woken());
567 assert!(wake_flag_2.is_woken());
568 }
569
570 #[test]
571 fn fifo_file_body_wakes_pending_wakers_if_no_readers_remain() {
572 let wake_flag_1 = Arc::new(WakeFlag::new());
573 let wake_flag_2 = Arc::new(WakeFlag::new());
574 let waker_1 = Rc::new(Cell::new(Some(Waker::from(wake_flag_1.clone()))));
575 let waker_2 = Rc::new(Cell::new(Some(Waker::from(wake_flag_2.clone()))));
576 let mut body = FileBody::Fifo {
577 content: VecDeque::new(),
578 readers: 2,
579 writers: 1,
580 pending_open_wakers: WakerSet::new(),
581 pending_read_wakers: WakerSet::from_iter([Rc::downgrade(&waker_1)]),
582 pending_write_wakers: WakerSet::from_iter([Rc::downgrade(&waker_2)]),
583 };
584
585 body.close(true, false);
588 assert!(!wake_flag_1.is_woken());
589 assert!(!wake_flag_2.is_woken());
590
591 body.close(true, false);
593 assert!(wake_flag_1.is_woken());
594 assert!(wake_flag_2.is_woken());
595 }
596
597 #[test]
598 fn fifo_file_body_is_ready_for_reading() {
599 let body = FileBody::Fifo {
602 content: VecDeque::new(),
603 readers: 0,
604 writers: 0,
605 pending_open_wakers: WakerSet::new(),
606 pending_read_wakers: WakerSet::new(),
607 pending_write_wakers: WakerSet::new(),
608 };
609 assert!(body.is_ready_for_reading());
610
611 let body = FileBody::Fifo {
614 content: VecDeque::new(),
615 readers: 0,
616 writers: 1,
617 pending_open_wakers: WakerSet::new(),
618 pending_read_wakers: WakerSet::new(),
619 pending_write_wakers: WakerSet::new(),
620 };
621 assert!(!body.is_ready_for_reading());
622 let body = FileBody::Fifo {
623 content: VecDeque::from([0]),
624 readers: 0,
625 writers: 1,
626 pending_open_wakers: WakerSet::new(),
627 pending_read_wakers: WakerSet::new(),
628 pending_write_wakers: WakerSet::new(),
629 };
630 assert!(body.is_ready_for_reading());
631 }
632
633 #[test]
634 fn fifo_file_body_is_ready_for_writing() {
635 let body = FileBody::Fifo {
638 content: VecDeque::new(),
639 readers: 0,
640 writers: 0,
641 pending_open_wakers: WakerSet::new(),
642 pending_read_wakers: WakerSet::new(),
643 pending_write_wakers: WakerSet::new(),
644 };
645 assert!(body.is_ready_for_writing());
646
647 let body = FileBody::Fifo {
650 content: VecDeque::from([0; PIPE_SIZE - PIPE_BUF]),
651 readers: 1,
652 writers: 0,
653 pending_open_wakers: WakerSet::new(),
654 pending_read_wakers: WakerSet::new(),
655 pending_write_wakers: WakerSet::new(),
656 };
657 assert!(body.is_ready_for_writing());
658 let body = FileBody::Fifo {
659 content: VecDeque::from([0; PIPE_SIZE - PIPE_BUF + 1]),
660 readers: 1,
661 writers: 0,
662 pending_open_wakers: WakerSet::new(),
663 pending_read_wakers: WakerSet::new(),
664 pending_write_wakers: WakerSet::new(),
665 };
666 assert!(!body.is_ready_for_writing());
667 }
668
669 #[test]
670 fn regular_file_body_read_beyond_file_length() {
671 let mut body = FileBody::new(b"hello");
672 let mut buffer = [0; 10];
673 assert_eq!(body.poll_read(&mut buffer, 5, Weak::new), Ready(Ok(0)));
674 assert_eq!(body.poll_read(&mut buffer, 10, Weak::new), Ready(Ok(0)));
675 }
676
677 #[test]
678 fn regular_file_body_read_more_than_content() {
679 let mut body = FileBody::new(b"hello");
680 let mut buffer = [0; 10];
681 assert_eq!(body.poll_read(&mut buffer, 2, Weak::new), Ready(Ok(3)));
682 assert_eq!(&buffer[..3], b"llo");
683 }
684
685 #[test]
686 fn regular_file_body_read_less_than_content() {
687 let mut body = FileBody::new(b"hello");
688 let mut buffer = [0; 3];
689 assert_eq!(body.poll_read(&mut buffer, 1, Weak::new), Ready(Ok(3)));
690 assert_eq!(&buffer, b"ell");
691 }
692
693 #[test]
694 fn fifo_file_body_read_eof() {
695 let mut body = FileBody::Fifo {
697 content: VecDeque::new(),
698 readers: 0,
699 writers: 0,
700 pending_open_wakers: WakerSet::new(),
701 pending_read_wakers: WakerSet::new(),
702 pending_write_wakers: WakerSet::new(),
703 };
704 let mut buffer = [0; 10];
705 assert_eq!(body.poll_read(&mut buffer, 0, Weak::new), Ready(Ok(0)));
706 }
707
708 #[test]
709 fn fifo_file_body_read_empty() {
710 let mut body = FileBody::Fifo {
713 content: VecDeque::new(),
714 readers: 1,
715 writers: 1,
716 pending_open_wakers: WakerSet::new(),
717 pending_read_wakers: WakerSet::new(),
718 pending_write_wakers: WakerSet::new(),
719 };
720 let mut buffer = [0; 10];
721
722 let wake_flag = Arc::new(WakeFlag::new());
723 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
724 let get_waker = || Rc::downgrade(&waker);
725 let poll = body.poll_read(&mut buffer, 0, get_waker);
726 assert_eq!(poll, Pending);
727 assert!(!wake_flag.is_woken());
728
729 let poll = body.poll_write(b"hello", 0, Weak::new);
731 assert_eq!(poll, Ready(Ok(5)));
732 assert!(wake_flag.is_woken());
733
734 let poll = body.poll_read(&mut buffer, 0, Weak::new);
736 assert_eq!(poll, Ready(Ok(5)));
737 assert_eq!(&buffer[..5], b"hello");
738 }
739
740 #[test]
741 fn fifo_file_body_read_empty_to_empty() {
742 let mut body = FileBody::Fifo {
745 content: VecDeque::new(),
746 readers: 1,
747 writers: 1,
748 pending_open_wakers: WakerSet::new(),
749 pending_read_wakers: WakerSet::new(),
750 pending_write_wakers: WakerSet::new(),
751 };
752
753 let wake_flag = Arc::new(WakeFlag::new());
754 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
755 let get_waker = || Rc::downgrade(&waker);
756 let poll = body.poll_read(&mut [], 0, get_waker);
757 assert_eq!(poll, Ready(Ok(0)));
758 assert!(!wake_flag.is_woken());
759 }
760
761 #[test]
762 fn fifo_file_body_read_non_empty() {
763 let mut body = FileBody::Fifo {
764 content: VecDeque::from(*b"hello"),
765 readers: 0,
766 writers: 0,
767 pending_open_wakers: WakerSet::new(),
768 pending_read_wakers: WakerSet::new(),
769 pending_write_wakers: WakerSet::new(),
770 };
771 let mut buffer = [0; 10];
772 assert_eq!(body.poll_read(&mut buffer, 0, Weak::new), Ready(Ok(5)));
773 assert_eq!(&buffer[..5], b"hello");
774 }
775
776 #[test]
777 fn regular_file_body_write_less_than_content() {
778 let mut body = FileBody::new(b"hello");
779 let buffer = b"ipp";
780 assert_eq!(body.poll_write(buffer, 1, Weak::new), Ready(Ok(3)));
781 assert_eq!(body, FileBody::new(b"hippo"));
782 }
783
784 #[test]
785 fn regular_file_body_write_more_than_content() {
786 let mut body = FileBody::new(b"hello");
787 let buffer = b"icopter";
788 assert_eq!(body.poll_write(buffer, 3, Weak::new), Ready(Ok(7)));
789 assert_eq!(body, FileBody::new(b"helicopter"));
790 }
791
792 #[test]
793 fn regular_file_body_write_beyond_file_length() {
794 let mut body = FileBody::new(b"hello");
795 let buffer = b"world";
796 assert_eq!(body.poll_write(buffer, 7, Weak::new), Ready(Ok(5)));
797 assert_eq!(body, FileBody::new(b"hello\0\0world"));
798 }
799
800 #[test]
801 fn fifo_file_body_write_closed() {
802 let mut body = FileBody::Fifo {
804 content: VecDeque::new(),
805 readers: 0,
806 writers: 0,
807 pending_open_wakers: WakerSet::new(),
808 pending_read_wakers: WakerSet::new(),
809 pending_write_wakers: WakerSet::new(),
810 };
811 let buffer = b"hello";
812 assert_eq!(
813 body.poll_write(buffer, 0, Weak::new),
814 Ready(Err(Errno::EPIPE))
815 );
816 }
817
818 #[test]
819 fn fifo_file_body_write_atomic_empty() {
820 let mut body = FileBody::Fifo {
823 content: VecDeque::from([0; PIPE_SIZE - PIPE_BUF]),
824 readers: 1,
825 writers: 0,
826 pending_open_wakers: WakerSet::new(),
827 pending_read_wakers: WakerSet::new(),
828 pending_write_wakers: WakerSet::new(),
829 };
830 let buffer = [0; PIPE_BUF];
831 assert_eq!(body.poll_write(&buffer, 0, Weak::new), Ready(Ok(PIPE_BUF)));
832 }
833
834 #[test]
835 fn fifo_file_body_write_atomic_full() {
836 let mut body = FileBody::Fifo {
840 content: VecDeque::from([0; PIPE_SIZE - PIPE_BUF + 1]),
841 readers: 1,
842 writers: 0,
843 pending_open_wakers: WakerSet::new(),
844 pending_read_wakers: WakerSet::new(),
845 pending_write_wakers: WakerSet::new(),
846 };
847 let buffer = [0; PIPE_BUF];
848
849 let wake_flag = Arc::new(WakeFlag::new());
850 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
851 let get_waker = || Rc::downgrade(&waker);
852 let poll = body.poll_write(&buffer, 0, get_waker);
853 assert_eq!(poll, Pending);
854 assert!(!wake_flag.is_woken());
855
856 let mut read_buffer = [0; 1];
858 let poll = body.poll_read(&mut read_buffer, 0, Weak::new);
859 assert_eq!(poll, Ready(Ok(1)));
860 assert!(wake_flag.is_woken());
861
862 let wake_flag = Arc::new(WakeFlag::new());
864 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
865 let get_waker = || Rc::downgrade(&waker);
866 let poll = body.poll_write(&buffer, 0, get_waker);
867 assert_eq!(poll, Ready(Ok(PIPE_BUF)));
868 assert!(!wake_flag.is_woken());
869 }
870
871 #[test]
872 fn fifo_file_body_write_non_atomic_empty() {
873 let mut body = FileBody::Fifo {
877 content: VecDeque::from([0; PIPE_SIZE - 1]),
878 readers: 1,
879 writers: 0,
880 pending_open_wakers: WakerSet::new(),
881 pending_read_wakers: WakerSet::new(),
882 pending_write_wakers: WakerSet::new(),
883 };
884 let buffer = [0; PIPE_BUF + 1];
885 assert_eq!(body.poll_write(&buffer, 0, Weak::new), Ready(Ok(1)));
886 }
887
888 #[test]
889 fn fifo_file_body_write_non_atomic_full() {
890 let mut body = FileBody::Fifo {
894 content: VecDeque::from([0; PIPE_SIZE]),
895 readers: 1,
896 writers: 0,
897 pending_open_wakers: WakerSet::new(),
898 pending_read_wakers: WakerSet::new(),
899 pending_write_wakers: WakerSet::new(),
900 };
901 let buffer = [0; PIPE_BUF + 1];
902
903 let wake_flag = Arc::new(WakeFlag::new());
904 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
905 let get_waker = || Rc::downgrade(&waker);
906 let poll = body.poll_write(&buffer, 0, get_waker);
907 assert_eq!(poll, Pending);
908 assert!(!wake_flag.is_woken());
909
910 let mut read_buffer = [0; 1];
912 let poll = body.poll_read(&mut read_buffer, 0, Weak::new);
913 assert_eq!(poll, Ready(Ok(1)));
914 assert!(wake_flag.is_woken());
915
916 let wake_flag = Arc::new(WakeFlag::new());
918 let waker = Rc::new(Cell::new(Some(Waker::from(wake_flag.clone()))));
919 let get_waker = || Rc::downgrade(&waker);
920 let poll = body.poll_write(&buffer, 0, get_waker);
921 assert_eq!(poll, Ready(Ok(1)));
922 assert!(!wake_flag.is_woken());
923 }
924}