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