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 = reinterpret_cast<SemaphoreTestSequenceHelper*>(context);
21   EXPECT_NE(helper, nullptr);
22   if (helper == nullptr) {
23     return;
24   }
25 
26   EXPECT_NE(helper->semaphore, nullptr);
27   if (helper->semaphore == nullptr) {
28     return;
29   }
30 
31   sleep(1);
32   ++helper->counter;
33   semaphore_post(helper->semaphore);
34 }
35 }  // namespace
36 
37 class SemaphoreTest : public ::testing::Test {};
38 
TEST_F(SemaphoreTest,test_new_simple)39 TEST_F(SemaphoreTest, test_new_simple) {
40   semaphore_t* semaphore = semaphore_new(0);
41   ASSERT_TRUE(semaphore != NULL);
42   semaphore_free(semaphore);
43 }
44 
TEST_F(SemaphoreTest,test_new_with_value)45 TEST_F(SemaphoreTest, test_new_with_value) {
46   semaphore_t* semaphore = semaphore_new(3);
47   ASSERT_TRUE(semaphore != NULL);
48 
49   EXPECT_TRUE(semaphore_try_wait(semaphore));
50   EXPECT_TRUE(semaphore_try_wait(semaphore));
51   EXPECT_TRUE(semaphore_try_wait(semaphore));
52   EXPECT_FALSE(semaphore_try_wait(semaphore));
53 
54   semaphore_free(semaphore);
55 }
56 
TEST_F(SemaphoreTest,test_try_wait)57 TEST_F(SemaphoreTest, test_try_wait) {
58   semaphore_t* semaphore = semaphore_new(0);
59   ASSERT_TRUE(semaphore != NULL);
60 
61   EXPECT_FALSE(semaphore_try_wait(semaphore));
62   semaphore_post(semaphore);
63   EXPECT_TRUE(semaphore_try_wait(semaphore));
64   EXPECT_FALSE(semaphore_try_wait(semaphore));
65 
66   semaphore_free(semaphore);
67 }
68 
TEST_F(SemaphoreTest,test_wait_after_post)69 TEST_F(SemaphoreTest, test_wait_after_post) {
70   semaphore_t* semaphore = semaphore_new(0);
71   ASSERT_TRUE(semaphore != NULL);
72   semaphore_post(semaphore);
73   semaphore_wait(semaphore);
74   semaphore_free(semaphore);
75 }
76 
TEST_F(SemaphoreTest,test_ensure_wait)77 TEST_F(SemaphoreTest, test_ensure_wait) {
78   semaphore_t* semaphore = semaphore_new(0);
79   ASSERT_TRUE(semaphore != NULL);
80   MessageLoopThread thread("semaphore_test_thread");
81   thread.StartUp();
82   ASSERT_TRUE(thread.IsRunning());
83 
84   EXPECT_FALSE(semaphore_try_wait(semaphore));
85   SemaphoreTestSequenceHelper sequence_helper = {semaphore, 0};
86   thread.DoInThread(FROM_HERE, base::BindOnce(sleep_then_increment_counter, &sequence_helper));
87   semaphore_wait(semaphore);
88   EXPECT_EQ(sequence_helper.counter, 1) << "semaphore_wait() did not wait for counter to increment";
89 
90   semaphore_free(semaphore);
91   thread.ShutDown();
92 }
93