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