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