1 #include "osi/semaphore.h"
2
3 #include <gtest/gtest.h>
4 #include <sys/select.h>
5 #include <unistd.h>
6
7 #include "common/message_loop_thread.h"
8 #include "osi/include/osi.h"
9 #include "osi/include/reactor.h"
10
11 using bluetooth::common::MessageLoopThread;
12
13 struct SemaphoreTestSequenceHelper {
14 semaphore_t* semaphore;
15 int counter;
16 };
17
18 namespace {
sleep_then_increment_counter(void * context)19 void sleep_then_increment_counter(void* context) {
20 SemaphoreTestSequenceHelper* helper =
21 reinterpret_cast<SemaphoreTestSequenceHelper*>(context);
22 EXPECT_NE(helper, nullptr);
23 if (helper == nullptr) {
24 return;
25 }
26
27 EXPECT_NE(helper->semaphore, nullptr);
28 if (helper->semaphore == nullptr) {
29 return;
30 }
31
32 sleep(1);
33 ++helper->counter;
34 semaphore_post(helper->semaphore);
35 }
36 } // namespace
37
38 class SemaphoreTest : public ::testing::Test {};
39
TEST_F(SemaphoreTest,test_new_simple)40 TEST_F(SemaphoreTest, test_new_simple) {
41 semaphore_t* semaphore = semaphore_new(0);
42 ASSERT_TRUE(semaphore != NULL);
43 semaphore_free(semaphore);
44 }
45
TEST_F(SemaphoreTest,test_new_with_value)46 TEST_F(SemaphoreTest, test_new_with_value) {
47 semaphore_t* semaphore = semaphore_new(3);
48 ASSERT_TRUE(semaphore != NULL);
49
50 EXPECT_TRUE(semaphore_try_wait(semaphore));
51 EXPECT_TRUE(semaphore_try_wait(semaphore));
52 EXPECT_TRUE(semaphore_try_wait(semaphore));
53 EXPECT_FALSE(semaphore_try_wait(semaphore));
54
55 semaphore_free(semaphore);
56 }
57
TEST_F(SemaphoreTest,test_try_wait)58 TEST_F(SemaphoreTest, test_try_wait) {
59 semaphore_t* semaphore = semaphore_new(0);
60 ASSERT_TRUE(semaphore != NULL);
61
62 EXPECT_FALSE(semaphore_try_wait(semaphore));
63 semaphore_post(semaphore);
64 EXPECT_TRUE(semaphore_try_wait(semaphore));
65 EXPECT_FALSE(semaphore_try_wait(semaphore));
66
67 semaphore_free(semaphore);
68 }
69
TEST_F(SemaphoreTest,test_wait_after_post)70 TEST_F(SemaphoreTest, test_wait_after_post) {
71 semaphore_t* semaphore = semaphore_new(0);
72 ASSERT_TRUE(semaphore != NULL);
73 semaphore_post(semaphore);
74 semaphore_wait(semaphore);
75 semaphore_free(semaphore);
76 }
77
TEST_F(SemaphoreTest,test_ensure_wait)78 TEST_F(SemaphoreTest, test_ensure_wait) {
79 semaphore_t* semaphore = semaphore_new(0);
80 ASSERT_TRUE(semaphore != NULL);
81 MessageLoopThread thread("semaphore_test_thread");
82 thread.StartUp();
83 ASSERT_TRUE(thread.IsRunning());
84
85 EXPECT_FALSE(semaphore_try_wait(semaphore));
86 SemaphoreTestSequenceHelper sequence_helper = {semaphore, 0};
87 thread.DoInThread(FROM_HERE, base::BindOnce(sleep_then_increment_counter,
88 &sequence_helper));
89 semaphore_wait(semaphore);
90 EXPECT_EQ(sequence_helper.counter, 1)
91 << "semaphore_wait() did not wait for counter to increment";
92
93 semaphore_free(semaphore);
94 thread.ShutDown();
95 }
96