summaryrefslogtreecommitdiffstats
path: root/third_party/rust/mio/test/test_notify.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/mio/test/test_notify.rs
parentInitial commit. (diff)
downloadfirefox-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.rs192
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();
+}