From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/mio/test/test_notify.rs | 192 +++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 third_party/rust/mio/test/test_notify.rs (limited to 'third_party/rust/mio/test/test_notify.rs') 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, + notify: usize +} + +impl TestHandler { + fn new(sender: Sender) -> TestHandler { + TestHandler { + sender, + notify: 0 + } + } +} + +impl Handler for TestHandler { + type Timeout = usize; + type Message = String; + + fn notify(&mut self, event_loop: &mut EventLoop, 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); + + impl Handler for Capacity { + type Message = i32; + type Timeout = (); + + fn notify(&mut self, event_loop: &mut EventLoop, 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::(); + 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); + + 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, 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(); +} -- cgit v1.2.3