diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/mio/test/test_notify.rs | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/mio/test/test_notify.rs')
-rw-r--r-- | third_party/rust/mio/test/test_notify.rs | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/third_party/rust/mio/test/test_notify.rs b/third_party/rust/mio/test/test_notify.rs new file mode 100644 index 0000000000..a6a8e51f67 --- /dev/null +++ b/third_party/rust/mio/test/test_notify.rs @@ -0,0 +1,192 @@ +use {localhost, sleep_ms}; +use mio::*; +use mio::deprecated::{EventLoop, EventLoopBuilder, Handler, Sender, NotifyError}; +use mio::net::TcpListener; +use std::thread; + +struct TestHandler { + sender: Sender<String>, + notify: usize +} + +impl TestHandler { + fn new(sender: Sender<String>) -> TestHandler { + TestHandler { + sender, + notify: 0 + } + } +} + +impl Handler for TestHandler { + type Timeout = usize; + type Message = String; + + fn notify(&mut self, event_loop: &mut EventLoop<TestHandler>, msg: String) { + match self.notify { + 0 => { + assert!(msg == "First", "actual={}", msg); + self.sender.send("Second".to_string()).unwrap(); + } + 1 => { + assert!(msg == "Second", "actual={}", msg); + event_loop.shutdown(); + } + v => panic!("unexpected value for notify; val={}", v) + } + + self.notify += 1; + } +} + +#[test] +pub fn test_notify() { + debug!("Starting TEST_NOTIFY"); + let mut event_loop = EventLoop::new().unwrap(); + + let addr = localhost(); + + // Setup a server socket so that the event loop blocks + let srv = TcpListener::bind(&addr).unwrap(); + + event_loop.register(&srv, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge()).unwrap(); + + let sender = event_loop.channel(); + + thread::spawn(move || { + sleep_ms(1_000); + sender.send("First".to_string()).unwrap(); + }); + + let sender = event_loop.channel(); + let mut handler = TestHandler::new(sender); + + // Start the event loop + event_loop.run(&mut handler).unwrap(); + + assert!(handler.notify == 2, "actual={}", handler.notify); +} + +#[test] +pub fn test_notify_capacity() { + use std::sync::mpsc::*; + use std::thread; + + struct Capacity(Receiver<i32>); + + impl Handler for Capacity { + type Message = i32; + type Timeout = (); + + fn notify(&mut self, event_loop: &mut EventLoop<Capacity>, msg: i32) { + if msg == 1 { + self.0.recv().unwrap(); + } else if msg == 3 { + event_loop.shutdown(); + } + } + } + + let mut builder = EventLoopBuilder::new(); + builder.notify_capacity(1); + + let (tx, rx) = channel::<i32>(); + let mut event_loop = builder.build().unwrap(); + let notify = event_loop.channel(); + + let handle = thread::spawn(move || { + let mut handler = Capacity(rx); + event_loop.run(&mut handler).unwrap(); + }); + + assert!(notify.send(1).is_ok()); + + loop { + if notify.send(2).is_err() { + break; + } + } + + tx.send(1).unwrap(); + + loop { + if notify.send(3).is_ok() { + break; + } + } + + handle.join().unwrap(); +} + +#[test] +pub fn test_notify_drop() { + use std::sync::mpsc::{self,Sender}; + use std::thread; + + struct MessageDrop(Sender<u8>); + + impl Drop for MessageDrop { + fn drop(&mut self) { + self.0.send(0).unwrap(); + } + } + + struct DummyHandler; + + impl Handler for DummyHandler { + type Timeout = (); + type Message = MessageDrop; + + fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: MessageDrop) { + msg.0.send(1).unwrap(); + drop(msg); + // We stop after the first message + event_loop.shutdown(); + } + } + + let (tx_notif_1, rx_notif_1) = mpsc::channel(); + let (tx_notif_2, rx_notif_2) = mpsc::channel(); + let (tx_notif_3, _unused) = mpsc::channel(); + let (tx_exit_loop, rx_exit_loop) = mpsc::channel(); + let (tx_drop_loop, rx_drop_loop) = mpsc::channel(); + + let mut event_loop = EventLoop::new().unwrap(); + let notify = event_loop.channel(); + + let handle = thread::spawn(move || { + let mut handler = DummyHandler; + event_loop.run(&mut handler).unwrap(); + + // Confirmation we exited the loop + tx_exit_loop.send(()).unwrap(); + + // Order to drop the loop + rx_drop_loop.recv().unwrap(); + drop(event_loop); + }); + notify.send(MessageDrop(tx_notif_1)).unwrap(); + assert_eq!(rx_notif_1.recv().unwrap(), 1); // Response from the loop + assert_eq!(rx_notif_1.recv().unwrap(), 0); // Drop notification + + // We wait for the event loop to exit before sending the second notification + rx_exit_loop.recv().unwrap(); + notify.send(MessageDrop(tx_notif_2)).unwrap(); + + // We ensure the message is indeed stuck in the queue + sleep_ms(100); + assert!(rx_notif_2.try_recv().is_err()); + + // Give the order to drop the event loop + tx_drop_loop.send(()).unwrap(); + assert_eq!(rx_notif_2.recv().unwrap(), 0); // Drop notification + + // Check that sending a new notification will return an error + // We should also get our message back + match notify.send(MessageDrop(tx_notif_3)).unwrap_err() { + NotifyError::Closed(Some(..)) => {} + _ => panic!(), + } + + handle.join().unwrap(); +} |