fn multishot_loom_change_waker<F>(f: F, expect: Result<i32, RecvError>)
    where
        F: FnOnce(Sender<i32>) + Send + Sync + Copy + 'static,
    {
        loom::model(move || {
            let test_waker1 = Arc::new(TestWaker::new());
            let waker1 = test_waker1.clone().into();
            let mut cx1 = Context::from_waker(&waker1);

            let test_waker2 = Arc::new(TestWaker::new());
            let waker2 = test_waker2.clone().into();
            let mut cx2 = Context::from_waker(&waker2);

            let (sender, mut receiver) = channel();

            thread::spawn({
                move || {
                    f(sender);
                }
            });

            let mut fut = receiver.recv();
            let mut fut = Pin::new(&mut fut);

            // Attempt to poll the future to completion with the provided context.
            fn try_complete(
                fut: &mut Pin<&mut Recv<i32>>,
                cx: &mut Context,
                other_cx: &mut Context,
                test_waker: &TestWaker,
                other_test_waker: &TestWaker,
                expect: Result<i32, RecvError>,
            ) -> bool {
                let res = fut.as_mut().poll(cx);

                // If `Ready` is returned we are done.
                if let Poll::Ready(val) = res {
                    assert_eq!(val, expect);
                    return true;
                }

                // The sender should not have used the other waker even if it
                // was registered before the last call to `poll`.
                assert_eq!(other_test_waker.take_count(), 0);

                // Although the last call to `poll` has returned `Pending`, the
                // sender may have been consumed in the meantime so check
                // whether there is a notification.
                let event_count = test_waker.take_count();
                if event_count != 0 {
                    // Expect only one notification.
                    assert_eq!(event_count, 1);

                    // Since the task was notified it is expected that the
                    // future is now ready.
                    let res = fut.as_mut().poll(other_cx);
                    assert_eq!(test_waker.take_count(), 0);
                    assert_eq!(other_test_waker.take_count(), 0);
                    assert_eq!(res, Poll::Ready(expect));
                    return true;
                }

                // The future was not polled to completion.
                false
            }

            // Poll with cx1.
            if try_complete(
                &mut fut,
                &mut cx1,
                &mut cx2,
                &test_waker1,
                &test_waker2,
                expect,
            ) {
                return;
            }
            // Poll with cx2.
            if try_complete(
                &mut fut,
                &mut cx2,
                &mut cx1,
                &test_waker2,
                &test_waker1,
                expect,
            ) {
                return;
            }
            // Poll again with cx1.
            if try_complete(
                &mut fut,
                &mut cx1,
                &mut cx2,
                &test_waker1,
                &test_waker2,
                expect,
            ) {
                return;
            }
        });
    }
// Executes a closure consuming the sender and checks the result of the
// completed future, changing the waker several times.
Executes a closure consuming the sender and checks the result of the
completed future, changing the waker several times.
Executes a closure consuming the sender and checks the result of the completed future changing the waker several times .
fn multishot_loom_change_waker<F>(f: F, expect: Result<i32, RecvError>)
    where
        F: FnOnce(Sender<i32>) + Send + Sync + Copy + 'static,
    {
        loom::model(move || {
            let test_waker1 = Arc::new(TestWaker::new());
            let waker1 = test_waker1.clone().into();
            let mut cx1 = Context::from_waker(&waker1);
            let test_waker2 = Arc::new(TestWaker::new());
            let waker2 = test_waker2.clone().into();
            let mut cx2 = Context::from_waker(&waker2);
            let (sender, mut receiver) = channel();
            thread::spawn({
                move || {
                    f(sender);
                }
            });
            let mut fut = receiver.recv();
            let mut fut = Pin::new(&mut fut);
            // Attempt to poll the future to completion with the provided context.
            fn try_complete(
                fut: &mut Pin<&mut Recv<i32>>,
                cx: &mut Context,
                other_cx: &mut Context,
                test_waker: &TestWaker,
                other_test_waker: &TestWaker,
                expect: Result<i32, RecvError>,
            ) -> bool {
                let res = fut.as_mut().poll(cx);
                // If `Ready` is returned we are done.
                if let Poll::Ready(val) = res {
                    assert_eq!(val, expect);
                    return true;
                }
                // The sender should not have used the other waker even if it
                // was registered before the last call to `poll`.
                assert_eq!(other_test_waker.take_count(), 0);
                // Although the last call to `poll` has returned `Pending`, the
                // sender may have been consumed in the meantime so check
                // whether there is a notification.
                let event_count = test_waker.take_count();
                if event_count != 0 {
                    // Expect only one notification.
                    assert_eq!(event_count, 1);
                    // Since the task was notified it is expected that the
                    // future is now ready.
                    let res = fut.as_mut().poll(other_cx);
                    assert_eq!(test_waker.take_count(), 0);
                    assert_eq!(other_test_waker.take_count(), 0);
                    assert_eq!(res, Poll::Ready(expect));
                    return true;
                }
                // The future was not polled to completion.
                false
            }
            // Poll with cx1.
            if try_complete(
                &mut fut,
                &mut cx1,
                &mut cx2,
                &test_waker1,
                &test_waker2,
                expect,
            ) {
                return;
            }
            // Poll with cx2.
            if try_complete(
                &mut fut,
                &mut cx2,
                &mut cx1,
                &test_waker2,
                &test_waker1,
                expect,
            ) {
                return;
            }
            // Poll again with cx1.
            if try_complete(
                &mut fut,
                &mut cx1,
                &mut cx2,
                &test_waker1,
                &test_waker2,
                expect,
            ) {
                return;
            }
        });
    }
fn multishot_loom_change_waker < F > ( f : F , expect : Result < i32 , RecvError > ) where F : FnOnce ( Sender < i32 > ) + Send + Sync + Copy + ' static , { loom :: model ( move | | { let test_waker1 = Arc :: new ( TestWaker :: new ( ) ) ; let waker1 = test_waker1 . clone ( ) . into ( ) ; let mut cx1 = Context :: from_waker ( & waker1 ) ; let test_waker2 = Arc :: new ( TestWaker :: new ( ) ) ; let waker2 = test_waker2 . clone ( ) . into ( ) ; let mut cx2 = Context :: from_waker ( & waker2 ) ; let ( sender , mut receiver ) = channel ( ) ; thread :: spawn ( { move | | { f ( sender ) ; } } ) ; let mut fut = receiver . recv ( ) ; let mut fut = Pin :: new ( & mut fut ) ; // Attempt to poll the future to completion with the provided context. fn try_complete ( fut : & mut Pin < & mut Recv < i32 > > , cx : & mut Context , other_cx : & mut Context , test_waker : & TestWaker , other_test_waker : & TestWaker , expect : Result < i32 , RecvError > , ) -> bool { let res = fut . as_mut ( ) . poll ( cx ) ; // If `Ready` is returned we are done. if let Poll :: Ready ( val ) = res { assert_eq ! ( val expect ) ; return true ; } // The sender should not have used the other waker even if it // was registered before the last call to `poll`. assert_eq ! ( other_test_waker take_count ( ) 0 ) ; // Although the last call to `poll` has returned `Pending`, the // sender may have been consumed in the meantime so check // whether there is a notification. let event_count = test_waker . take_count ( ) ; if event_count != 0 { // Expect only one notification. assert_eq ! ( event_count 1 ) ; // Since the task was notified it is expected that the // future is now ready. let res = fut . as_mut ( ) . poll ( other_cx ) ; assert_eq ! ( test_waker take_count ( ) 0 ) ; assert_eq ! ( other_test_waker take_count ( ) 0 ) ; assert_eq ! ( res Poll Ready ( expect ) ) ; return true ; } // The future was not polled to completion. false } // Poll with cx1. if try_complete ( & mut fut , & mut cx1 , & mut cx2 , & test_waker1 , & test_waker2 , expect , ) { return ; } // Poll with cx2. if try_complete ( & mut fut , & mut cx2 , & mut cx1 , & test_waker2 , & test_waker1 , expect , ) { return ; } // Poll again with cx1. if try_complete ( & mut fut , & mut cx1 , & mut cx2 , & test_waker1 , & test_waker2 , expect , ) { return ; } } ) ; }
Executes a closure consuming the sender and checks the result of the
completed future, changing the waker several times.
Executes a closure consuming the sender and checks the result of the completed future changing the waker several times .
f
F
expect
Result<i32, RecvError>