• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_thread/deprecated_or_new_thread_function.h"
16 
17 #include "pw_unit_test/framework.h"
18 
19 namespace {
20 
21 using ::pw::Function;
22 using ::pw::thread::DeprecatedFnPtrAndArg;
23 using ::pw::thread::DeprecatedOrNewThreadFn;
24 
TEST(DeprecatedOrNewThreadFunction,CallInvokesLambda)25 TEST(DeprecatedOrNewThreadFunction, CallInvokesLambda) {
26   int call_count = 0;
27   DeprecatedOrNewThreadFn fn;
28   fn = Function<void()>([&call_count]() { ++call_count; });
29   EXPECT_EQ(call_count, 0);
30   fn();
31   EXPECT_EQ(call_count, 1);
32 }
33 
TEST(DeprecatedOrNewThreadFunction,CallMovedInvokesLambda)34 TEST(DeprecatedOrNewThreadFunction, CallMovedInvokesLambda) {
35   int call_count = 0;
36   DeprecatedOrNewThreadFn fn;
37   fn = Function<void()>([&call_count]() { ++call_count; });
38   DeprecatedOrNewThreadFn fn2;
39   fn2 = std::move(fn);
40   EXPECT_EQ(call_count, 0);
41   fn2();
42   EXPECT_EQ(call_count, 1);
43 }
44 
45 class DestroyCounter {
46  public:
DestroyCounter(int & counter)47   DestroyCounter(int& counter) : counter_(&counter) {}
48   DestroyCounter(const DestroyCounter&) = delete;
49   DestroyCounter& operator=(const DestroyCounter&) = delete;
DestroyCounter(DestroyCounter && other)50   DestroyCounter(DestroyCounter&& other) : counter_(other.counter_) {
51     other.counter_ = nullptr;
52   }
operator =(DestroyCounter && other)53   DestroyCounter& operator=(DestroyCounter&& other) {
54     CounterIncrement();
55     counter_ = other.counter_;
56     other.counter_ = nullptr;
57     return *this;
58   }
~DestroyCounter()59   ~DestroyCounter() { CounterIncrement(); }
60 
61  private:
CounterIncrement()62   void CounterIncrement() {
63     if (counter_ != nullptr) {
64       ++(*counter_);
65     }
66   }
67   int* counter_;
68 };
69 
TEST(DeprecatedOrNewThreadFunction,DestructionInvokesLambdasDestructor)70 TEST(DeprecatedOrNewThreadFunction, DestructionInvokesLambdasDestructor) {
71   int counter = 0;
72   {
73     DeprecatedOrNewThreadFn fn;
74     fn = Function<void()>([_unused = DestroyCounter(counter)]() {});
75     EXPECT_EQ(counter, 0);
76   }
77   EXPECT_EQ(counter, 1);
78 }
79 
TEST(DeprecatedOrNewThreadFunction,DestructionMovedInvokesLambdasDestructor)80 TEST(DeprecatedOrNewThreadFunction, DestructionMovedInvokesLambdasDestructor) {
81   int counter = 0;
82   {
83     DeprecatedOrNewThreadFn fn;
84     {
85       fn = Function<void()>([_unused = DestroyCounter(counter)]() {});
86       DeprecatedOrNewThreadFn scoped_fn;
87       scoped_fn = std::move(fn);
88       EXPECT_EQ(counter, 0);
89     }
90     EXPECT_EQ(counter, 1);
91   }
92   EXPECT_EQ(counter, 1);
93 }
94 
TEST(DeprecatedOrNewThreadFunction,NullptrAssignmentInvokesLambdasDestructor)95 TEST(DeprecatedOrNewThreadFunction, NullptrAssignmentInvokesLambdasDestructor) {
96   int counter = 0;
97   {
98     DeprecatedOrNewThreadFn fn;
99     fn = Function<void()>([_unused = DestroyCounter(counter)]() {});
100     EXPECT_EQ(counter, 0);
101     fn = nullptr;
102     EXPECT_EQ(counter, 1);
103   }
104   EXPECT_EQ(counter, 1);
105 }
106 
increment(void * int_to_increment)107 void increment(void* int_to_increment) {
108   int& value = *static_cast<int*>(int_to_increment);
109   ++value;
110 }
111 
TEST(DeprecatedOrNewThreadFunction,CallInvokesFnPtrWithArg)112 TEST(DeprecatedOrNewThreadFunction, CallInvokesFnPtrWithArg) {
113   int call_count = 0;
114   DeprecatedOrNewThreadFn fn;
115   fn = DeprecatedFnPtrAndArg{increment, static_cast<void*>(&call_count)};
116   EXPECT_EQ(call_count, 0);
117   fn();
118   EXPECT_EQ(call_count, 1);
119 }
120 
TEST(DeprecatedOrNewThreadFunction,CallMovedInvokesFnPtrWithArg)121 TEST(DeprecatedOrNewThreadFunction, CallMovedInvokesFnPtrWithArg) {
122   int call_count = 0;
123   DeprecatedOrNewThreadFn fn;
124   fn = DeprecatedFnPtrAndArg{increment, static_cast<void*>(&call_count)};
125   DeprecatedOrNewThreadFn fn2;
126   fn2 = std::move(fn);
127   EXPECT_EQ(call_count, 0);
128   fn2();
129   EXPECT_EQ(call_count, 1);
130 }
131 
132 }  // namespace
133