xref: /aosp_15_r20/external/pigweed/pw_async2/pendable_as_task_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_async2/pendable_as_task.h"
16 
17 #include "pw_async2/dispatcher.h"
18 #include "pw_unit_test/framework.h"
19 
20 namespace {
21 
22 using ::pw::async2::Context;
23 using ::pw::async2::Dispatcher;
24 using ::pw::async2::PendableAsTask;
25 using ::pw::async2::Pending;
26 using ::pw::async2::Poll;
27 using ::pw::async2::Ready;
28 using ::pw::async2::Waker;
29 
30 struct StructWithPendMethod {
StructWithPendMethod__anonca40c9130111::StructWithPendMethod31   StructWithPendMethod(int& poll_count, bool& allow_completion, Waker& waker)
32       : poll_count_(poll_count),
33         allow_completion_(allow_completion),
34         waker_(waker) {}
35 
Pend__anonca40c9130111::StructWithPendMethod36   Poll<> Pend(Context& cx) {
37     ++poll_count_;
38     if (allow_completion_) {
39       return Ready();
40     }
41     PW_ASYNC_STORE_WAKER(
42         cx, waker_, "StructWithPendMethod is waiting for waker_");
43     return Pending();
44   }
45 
46   int& poll_count_;
47   bool& allow_completion_;
48   Waker& waker_;
49 };
50 
TEST(PendableAsTask,PendDelegatesToPendable)51 TEST(PendableAsTask, PendDelegatesToPendable) {
52   Dispatcher dispatcher;
53 
54   int poll_count = 0;
55   bool allow_completion = false;
56   Waker waker;
57   StructWithPendMethod pendable(poll_count, allow_completion, waker);
58   PendableAsTask task(std::move(pendable));
59 
60   dispatcher.Post(task);
61 
62   EXPECT_EQ(poll_count, 0);
63   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
64   EXPECT_EQ(poll_count, 1);
65 
66   // Unwoken task is not polled.
67   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
68   EXPECT_EQ(poll_count, 1);
69 
70   std::move(waker).Wake();
71   allow_completion = true;
72   EXPECT_EQ(dispatcher.RunUntilStalled(), Ready());
73   EXPECT_EQ(poll_count, 2);
74 }
75 
TEST(PendableAsTask,PendDelegatesToPendablePtr)76 TEST(PendableAsTask, PendDelegatesToPendablePtr) {
77   Dispatcher dispatcher;
78 
79   int poll_count = 0;
80   bool allow_completion = false;
81   Waker waker;
82   StructWithPendMethod pendable(poll_count, allow_completion, waker);
83   // Note the lack of `std::move` or a copy-- we pass a ptr.
84   PendableAsTask task(&pendable);
85 
86   dispatcher.Post(task);
87 
88   EXPECT_EQ(poll_count, 0);
89   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
90   EXPECT_EQ(poll_count, 1);
91 
92   // Unwoken task is not polled.
93   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
94   EXPECT_EQ(poll_count, 1);
95 
96   std::move(waker).Wake();
97   allow_completion = true;
98   EXPECT_EQ(dispatcher.RunUntilStalled(), Ready());
99   EXPECT_EQ(poll_count, 2);
100 }
101 
102 }  // namespace
103