diff --git a/system/osi/Android.bp b/system/osi/Android.bp index 9a3bf1c916a56cb2752e923faf9b8fb3706d8077..25e594b3b26d7628a929580807e620b5afa65962 100644 --- a/system/osi/Android.bp +++ b/system/osi/Android.bp @@ -59,6 +59,12 @@ cc_library_static { "//packages/apps/Test/connectivity/sl4n", "//packages/modules/Bluetooth:__subpackages__", ], + export_include_dirs: [ + "include", + ], + local_include_dirs: [ + "include_internal", + ], defaults: ["fluoride_osi_defaults", "fluoride_basic_defaults"], // TODO(mcchou): Remove socket_utils sources after platform specific // dependencies are abstracted. @@ -79,13 +85,15 @@ cc_library_static { "src/properties.cc", "src/reactor.cc", "src/ringbuffer.cc", - "src/semaphore.cc", "src/socket.cc", "src/socket_utils/socket_local_client.cc", "src/socket_utils/socket_local_server.cc", "src/thread.cc", "src/thread_scheduler.cc", "src/wakelock.cc", + + // internal source that should not be used outside of libosi + "src/internal/semaphore.cc", ], host_supported: true, // TODO(armansito): Setting _GNU_SOURCE isn't very platform-independent but @@ -99,6 +107,9 @@ cc_library_static { ], }, }, + cflags: [ + "-DLIB_OSI_INTERNAL", + ], min_sdk_version: "Tiramisu", apex_available: [ "com.android.btservices", @@ -130,9 +141,11 @@ cc_test { "test/rand_test.cc", "test/reactor_test.cc", "test/ringbuffer_test.cc", - "test/semaphore_test.cc", "test/thread_test.cc", "test/wakelock_test.cc", + + // test internal sources only used inside the libosi + "test/internal/semaphore_test.cc", ], shared_libs: [ "android.hardware.bluetooth@1.0", @@ -143,6 +156,10 @@ cc_test { "libcutils", "libcrypto", ], + local_include_dirs: [ + "include_internal", + "test", + ], static_libs: [ "libbt-common", "libbt-protos-lite", @@ -155,6 +172,9 @@ cc_test { cflags: ["-DOS_GENERIC"], }, }, + cflags: [ + "-DLIB_OSI_INTERNAL", + ], sanitize: { cfi: false, }, diff --git a/system/osi/BUILD.gn b/system/osi/BUILD.gn index ceb30da4963d447c5b72859e0f1246fc3c08b30c..0f14260d658d1afee9afa3481e9fc92223b66cd8 100644 --- a/system/osi/BUILD.gn +++ b/system/osi/BUILD.gn @@ -32,7 +32,6 @@ static_library("osi") { "src/properties.cc", "src/reactor.cc", "src/ringbuffer.cc", - "src/semaphore.cc", "src/socket.cc", # TODO(mcchou): Remove these sources after platform specific @@ -41,14 +40,22 @@ static_library("osi") { "src/socket_utils/socket_local_server.cc", "src/thread.cc", "src/wakelock.cc", + + # internal dependencies to not be used outside + "src/internal/semaphore.cc", ] include_dirs = [ "//bt/system/", - "//bt/system/linux_include", "//bt/system/internal_include", - "//bt/system/utils/include", + "//bt/system/linux_include", + "//bt/system/osi/include_internal", "//bt/system/stack/include", + "//bt/system/utils/include", + ] + + cflags = [ + "-DLIB_OSI_INTERNAL", ] deps = [ @@ -79,13 +86,20 @@ if (use.test) { "test/reactor_test.cc", "test/ringbuffer_test.cc", "test/thread_test.cc", + + "test/internal/semaphore_test.cc", ] include_dirs = [ "//bt/system/", + "//bt/system/osi/include_internal", "//bt/system/osi/test", ] + cflags = [ + "-DLIB_OSI_INTERNAL", + ] + deps = [ "//bt/system/osi", ] diff --git a/system/osi/include/semaphore.h b/system/osi/include_internal/osi/semaphore.h similarity index 96% rename from system/osi/include/semaphore.h rename to system/osi/include_internal/osi/semaphore.h index 3ae5e0fd63677f3af64eef81edcebe85442e8518..2fa3a9f49c9f355baf2c1d2179a52e5b37e9d5f0 100644 --- a/system/osi/include/semaphore.h +++ b/system/osi/include_internal/osi/semaphore.h @@ -18,6 +18,10 @@ #pragma once +#ifndef LIB_OSI_INTERNAL +#error "Please do not include this outside of osi." +#endif + #include <stdbool.h> struct semaphore_t; diff --git a/system/osi/src/alarm.cc b/system/osi/src/alarm.cc index 19baacbd68226e4a0944663ba9787f19addf6736..2f0a27ea71c1fde6e9d638e3064f08874250b7f5 100644 --- a/system/osi/src/alarm.cc +++ b/system/osi/src/alarm.cc @@ -43,9 +43,9 @@ #include "osi/include/list.h" #include "osi/include/log.h" #include "osi/include/osi.h" -#include "osi/include/semaphore.h" #include "osi/include/thread.h" #include "osi/include/wakelock.h" +#include "osi/semaphore.h" #include "stack/include/btu.h" using base::Bind; diff --git a/system/osi/src/fixed_queue.cc b/system/osi/src/fixed_queue.cc index b386fd9076360576e9797d8b99ef101027ee3cb5..f2fbf6a3263c8253e88450118e5228141ddda078 100644 --- a/system/osi/src/fixed_queue.cc +++ b/system/osi/src/fixed_queue.cc @@ -27,7 +27,7 @@ #include "osi/include/list.h" #include "osi/include/osi.h" #include "osi/include/reactor.h" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" typedef struct fixed_queue_t { list_t* list; diff --git a/system/osi/src/future.cc b/system/osi/src/future.cc index 878b5ad6b4931371a3d2a6a97ba2bc73d58f50f5..fe97b9c393f8346229992bd80d9feec79fb7a724 100644 --- a/system/osi/src/future.cc +++ b/system/osi/src/future.cc @@ -26,7 +26,7 @@ #include "osi/include/allocator.h" #include "osi/include/log.h" #include "osi/include/osi.h" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" struct future_t { bool ready_can_be_called; diff --git a/system/osi/src/semaphore.cc b/system/osi/src/internal/semaphore.cc similarity index 98% rename from system/osi/src/semaphore.cc rename to system/osi/src/internal/semaphore.cc index f209d728905039028a2559406d1b3727bc29217e..fb95e2b14a5c6e413df0750e4c9ed5635875691a 100644 --- a/system/osi/src/semaphore.cc +++ b/system/osi/src/internal/semaphore.cc @@ -18,7 +18,7 @@ #define LOG_TAG "bt_osi_semaphore" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" #include <base/logging.h> #include <errno.h> diff --git a/system/osi/src/thread.cc b/system/osi/src/thread.cc index a8ac5ad7bb1315fa65f2a373ad825751bc7ed770..d4528c96d95b3e9798fd89f3210e30d929e04988 100644 --- a/system/osi/src/thread.cc +++ b/system/osi/src/thread.cc @@ -38,7 +38,7 @@ #include "osi/include/fixed_queue.h" #include "osi/include/log.h" #include "osi/include/reactor.h" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" struct thread_t { std::atomic_bool is_joined{false}; diff --git a/system/osi/test/alarm_test.cc b/system/osi/test/alarm_test.cc index 7c30bf353e188521f250092db26ae1682c8303d6..7b42bbc9fe963282cee6ea3faa01ef2932c4901c 100644 --- a/system/osi/test/alarm_test.cc +++ b/system/osi/test/alarm_test.cc @@ -25,7 +25,7 @@ #include "osi/include/alarm.h" #include "osi/include/fixed_queue.h" #include "osi/include/osi.h" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" using base::Closure; using base::TimeDelta; diff --git a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc index c432f8c5c1d80bce6e82fb8c7cd9d3a4e25b69ed..126078ded39b30a1d94b5c6566d089bd8ea4f633 100644 --- a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc +++ b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc @@ -17,7 +17,6 @@ #include <fcntl.h> #include <fuzzer/FuzzedDataProvider.h> #include "osi/include/alarm.h" -#include "osi/include/semaphore.h" #include "common/message_loop_thread.h" @@ -29,7 +28,37 @@ using bluetooth::common::MessageLoopThread; #define MAX_BUFFER_LEN 4096 #define MAX_ALARM_DURATION 25 -static semaphore_t* semaphore; +class btsemaphore { + public: + void post() { + std::lock_guard<std::mutex> lock(mMutex); + ++mCount; + mCondition.notify_one(); + } + + void wait() { + std::unique_lock<std::mutex> lock(mMutex); + while (!mCount) { + mCondition.wait(lock); + } + --mCount; + } + + bool try_wait() { + std::lock_guard<std::mutex> lock(mMutex); + if (mCount) { + --mCount; + return true; + } + return false; + } + + private: + std::mutex mMutex; + std::condition_variable mCondition; + unsigned long mCount = 0; +}; +static btsemaphore semaphore; static int cb_counter; static MessageLoopThread* thread = new MessageLoopThread("fake main thread"); @@ -37,14 +66,13 @@ bluetooth::common::MessageLoopThread* get_main_thread() { return thread; } static void cb(void* data) { ++cb_counter; - semaphore_post(semaphore); + semaphore.post(); } void setup() { cb_counter = 0; - semaphore = semaphore_new(0); } -void teardown() { semaphore_free(semaphore); } +void teardown() { } alarm_t* fuzz_init_alarm(FuzzedDataProvider* dataProvider) { size_t name_len = @@ -130,7 +158,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // Wait for them to complete for (int i = 1; i <= num_alarms; i++) { - semaphore_wait(semaphore); + semaphore.wait(); } } diff --git a/system/osi/test/semaphore_test.cc b/system/osi/test/internal/semaphore_test.cc similarity index 98% rename from system/osi/test/semaphore_test.cc rename to system/osi/test/internal/semaphore_test.cc index 54046a85159f118ec33726024ba066589c0f879d..41851811d2ddd4c3ca8d0815c8c1ca62f53f9cbe 100644 --- a/system/osi/test/semaphore_test.cc +++ b/system/osi/test/internal/semaphore_test.cc @@ -9,7 +9,7 @@ #include "common/message_loop_thread.h" #include "osi/include/osi.h" #include "osi/include/reactor.h" -#include "osi/include/semaphore.h" +#include "osi/semaphore.h" using bluetooth::common::MessageLoopThread; diff --git a/system/test/mock/mock_osi_alarm.h b/system/test/mock/mock_osi_alarm.h index 18c15aec9aa9abc3331838013013ef21e11d32f1..88ae09e5a9f542fd164046e2430ea69471a27918 100644 --- a/system/test/mock/mock_osi_alarm.h +++ b/system/test/mock/mock_osi_alarm.h @@ -56,7 +56,6 @@ extern std::map<std::string, int> mock_function_count_map; #include "osi/include/list.h" #include "osi/include/log.h" #include "osi/include/osi.h" -#include "osi/include/semaphore.h" #include "osi/include/thread.h" #include "osi/include/wakelock.h" diff --git a/system/test/mock/mock_osi_fixed_queue.h b/system/test/mock/mock_osi_fixed_queue.h index 0534ef8b9691d229ef6ac2a0a2e080548f5ea76a..e14b4a3fc434b78898616f80a3e2960a4fff4a73 100644 --- a/system/test/mock/mock_osi_fixed_queue.h +++ b/system/test/mock/mock_osi_fixed_queue.h @@ -45,7 +45,6 @@ extern std::map<std::string, int> mock_function_count_map; #include "osi/include/list.h" #include "osi/include/osi.h" #include "osi/include/reactor.h" -#include "osi/include/semaphore.h" // Mocked compile conditionals, if any diff --git a/system/test/mock/mock_osi_future.h b/system/test/mock/mock_osi_future.h index 7d95b85bfe161f1abcc7545d921639bca485ad3f..c77460a2f3cf7d5ca34f1c29133c7a77aecb42fc 100644 --- a/system/test/mock/mock_osi_future.h +++ b/system/test/mock/mock_osi_future.h @@ -41,7 +41,6 @@ extern std::map<std::string, int> mock_function_count_map; #include "osi/include/future.h" #include "osi/include/log.h" #include "osi/include/osi.h" -#include "osi/include/semaphore.h" // Mocked compile conditionals, if any diff --git a/system/test/mock/mock_osi_semaphore.cc b/system/test/mock/mock_osi_semaphore.cc deleted file mode 100644 index 4a69c0e16e6f10b7fd4ad6bd1c048f000e88703e..0000000000000000000000000000000000000000 --- a/system/test/mock/mock_osi_semaphore.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Generated mock file from original source file - * Functions generated:6 - * - * mockcify.pl ver 0.3.0 - */ - -#include <cstdint> -#include <functional> -#include <map> -#include <string> - -extern std::map<std::string, int> mock_function_count_map; - -// Mock include file to share data between tests and mock -#include "test/mock/mock_osi_semaphore.h" - -// Mocked internal structures, if any - -namespace test { -namespace mock { -namespace osi_semaphore { - -// Function state capture and return values, if needed -struct semaphore_free semaphore_free; -struct semaphore_get_fd semaphore_get_fd; -struct semaphore_new semaphore_new; -struct semaphore_post semaphore_post; -struct semaphore_try_wait semaphore_try_wait; -struct semaphore_wait semaphore_wait; - -} // namespace osi_semaphore -} // namespace mock -} // namespace test - -// Mocked functions, if any -void semaphore_free(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - test::mock::osi_semaphore::semaphore_free(semaphore); -} -int semaphore_get_fd(const semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - return test::mock::osi_semaphore::semaphore_get_fd(semaphore); -} -semaphore_t* semaphore_new(unsigned int value) { - mock_function_count_map[__func__]++; - return test::mock::osi_semaphore::semaphore_new(value); -} -void semaphore_post(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - test::mock::osi_semaphore::semaphore_post(semaphore); -} -bool semaphore_try_wait(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - return test::mock::osi_semaphore::semaphore_try_wait(semaphore); -} -void semaphore_wait(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - test::mock::osi_semaphore::semaphore_wait(semaphore); -} -// Mocked functions complete -// END mockcify generation diff --git a/system/test/mock/mock_osi_semaphore.h b/system/test/mock/mock_osi_semaphore.h deleted file mode 100644 index ca862ea03bb76dd0e603cfa62982ba6b7d9270f7..0000000000000000000000000000000000000000 --- a/system/test/mock/mock_osi_semaphore.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Generated mock file from original source file - * Functions generated:6 - * - * mockcify.pl ver 0.3.0 - */ - -#include <cstdint> -#include <functional> -#include <map> -#include <string> - -extern std::map<std::string, int> mock_function_count_map; - -// Original included files, if any -// NOTE: Since this is a mock file with mock definitions some number of -// include files may not be required. The include-what-you-use -// still applies, but crafting proper inclusion is out of scope -// for this effort. This compilation unit may compile as-is, or -// may need attention to prune from (or add to ) the inclusion set. -#include <base/logging.h> -#include <errno.h> -#include <fcntl.h> -#include <malloc.h> -#include <string.h> -#include <sys/eventfd.h> -#include <unistd.h> - -#include "check.h" -#include "osi/include/allocator.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" -#include "osi/include/semaphore.h" - -// Mocked compile conditionals, if any - -namespace test { -namespace mock { -namespace osi_semaphore { - -// Shared state between mocked functions and tests -// Name: semaphore_free -// Params: semaphore_t* semaphore -// Return: void -struct semaphore_free { - std::function<void(semaphore_t* semaphore)> body{ - [](semaphore_t* semaphore) {}}; - void operator()(semaphore_t* semaphore) { body(semaphore); }; -}; -extern struct semaphore_free semaphore_free; - -// Name: semaphore_get_fd -// Params: const semaphore_t* semaphore -// Return: int -struct semaphore_get_fd { - int return_value{0}; - std::function<int(const semaphore_t* semaphore)> body{ - [this](const semaphore_t* semaphore) { return return_value; }}; - int operator()(const semaphore_t* semaphore) { return body(semaphore); }; -}; -extern struct semaphore_get_fd semaphore_get_fd; - -// Name: semaphore_new -// Params: unsigned int value -// Return: semaphore_t* -struct semaphore_new { - semaphore_t* return_value{0}; - std::function<semaphore_t*(unsigned int value)> body{ - [this](unsigned int value) { return return_value; }}; - semaphore_t* operator()(unsigned int value) { return body(value); }; -}; -extern struct semaphore_new semaphore_new; - -// Name: semaphore_post -// Params: semaphore_t* semaphore -// Return: void -struct semaphore_post { - std::function<void(semaphore_t* semaphore)> body{ - [](semaphore_t* semaphore) {}}; - void operator()(semaphore_t* semaphore) { body(semaphore); }; -}; -extern struct semaphore_post semaphore_post; - -// Name: semaphore_try_wait -// Params: semaphore_t* semaphore -// Return: bool -struct semaphore_try_wait { - bool return_value{false}; - std::function<bool(semaphore_t* semaphore)> body{ - [this](semaphore_t* semaphore) { return return_value; }}; - bool operator()(semaphore_t* semaphore) { return body(semaphore); }; -}; -extern struct semaphore_try_wait semaphore_try_wait; - -// Name: semaphore_wait -// Params: semaphore_t* semaphore -// Return: void -struct semaphore_wait { - std::function<void(semaphore_t* semaphore)> body{ - [](semaphore_t* semaphore) {}}; - void operator()(semaphore_t* semaphore) { body(semaphore); }; -}; -extern struct semaphore_wait semaphore_wait; - -} // namespace osi_semaphore -} // namespace mock -} // namespace test - -// END mockcify generation \ No newline at end of file diff --git a/system/test/mock/mock_osi_thread.h b/system/test/mock/mock_osi_thread.h index 7bcab0849f10e5a006884fcc6675dd1e93616fce..042b3a686c48649ee54abc664e833272ab74e016 100644 --- a/system/test/mock/mock_osi_thread.h +++ b/system/test/mock/mock_osi_thread.h @@ -52,7 +52,6 @@ extern std::map<std::string, int> mock_function_count_map; #include "osi/include/fixed_queue.h" #include "osi/include/log.h" #include "osi/include/reactor.h" -#include "osi/include/semaphore.h" #include "osi/include/thread.h" // Mocked compile conditionals, if any diff --git a/system/test/stub/osi.cc b/system/test/stub/osi.cc index 6c879471c2f1e35d62a22bdc00d7d33b7c44cc1e..844e7576d2a83b1f39f3ea8f4f292137182f955c 100644 --- a/system/test/stub/osi.cc +++ b/system/test/stub/osi.cc @@ -41,7 +41,6 @@ extern std::map<std::string, int> mock_function_count_map; #include "osi/include/osi.h" #include "osi/include/reactor.h" #include "osi/include/ringbuffer.h" -#include "osi/include/semaphore.h" #include "osi/include/socket.h" #include "osi/include/thread.h" #include "osi/include/wakelock.h" @@ -626,28 +625,6 @@ int32_t osi_property_get_int32(const char* key, int32_t default_value) { return 0; } -bool semaphore_try_wait(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - return false; -} -int semaphore_get_fd(const semaphore_t* semaphore) { - mock_function_count_map[__func__]++; - return 0; -} -semaphore_t* semaphore_new(unsigned int value) { - mock_function_count_map[__func__]++; - return nullptr; -} -void semaphore_free(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; -} -void semaphore_post(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; -} -void semaphore_wait(semaphore_t* semaphore) { - mock_function_count_map[__func__]++; -} - bool wakelock_acquire(void) { mock_function_count_map[__func__]++; return false; diff --git a/system/test/suite/adapter/bluetooth_test.cc b/system/test/suite/adapter/bluetooth_test.cc index 6b24b7509c801df75c58b436af90995092fb1d34..79ce2a31f23fc28f6bb7130d5ac508fc0a048344 100644 --- a/system/test/suite/adapter/bluetooth_test.cc +++ b/system/test/suite/adapter/bluetooth_test.cc @@ -34,6 +34,16 @@ std::mutex callback_lock; } // namespace +void semaphore_wait(btsemaphore &s) { + s.wait(); +} +void semaphore_post(btsemaphore &s) { + s.post(); +} +void semaphore_try_wait(btsemaphore &s) { + s.try_wait(); +} + namespace bttest { void BluetoothTest::SetUp() { @@ -53,10 +63,6 @@ void BluetoothTest::SetUp() { bluetooth::hal::BluetoothInterface::Initialize(); ASSERT_TRUE(bluetooth::hal::BluetoothInterface::IsInitialized()); - adapter_properties_callback_sem_ = semaphore_new(0); - remote_device_properties_callback_sem_ = semaphore_new(0); - adapter_state_changed_callback_sem_ = semaphore_new(0); - discovery_state_changed_callback_sem_ = semaphore_new(0); auto bt_hal_interface = bluetooth::hal::BluetoothInterface::Get(); bt_hal_interface->AddObserver(this); @@ -65,10 +71,6 @@ void BluetoothTest::SetUp() { } void BluetoothTest::TearDown() { - semaphore_free(adapter_properties_callback_sem_); - semaphore_free(remote_device_properties_callback_sem_); - semaphore_free(adapter_state_changed_callback_sem_); - semaphore_free(discovery_state_changed_callback_sem_); auto bt_hal_interface = bluetooth::hal::BluetoothInterface::Get(); bt_hal_interface->RemoveObserver(this); @@ -76,8 +78,8 @@ void BluetoothTest::TearDown() { ASSERT_FALSE(bt_hal_interface->IsInitialized()); } -void BluetoothTest::ClearSemaphore(semaphore_t* sem) { - while (semaphore_try_wait(sem)) +void BluetoothTest::ClearSemaphore(btsemaphore& sem) { + while (sem.try_wait()) ; } diff --git a/system/test/suite/adapter/bluetooth_test.h b/system/test/suite/adapter/bluetooth_test.h index 6b50be9f95d04fc8d79b9d22de5f0ed06edbfdee..d1946bd0e9b37dcd3e35a98c2a0e652643c6a2a3 100644 --- a/system/test/suite/adapter/bluetooth_test.h +++ b/system/test/suite/adapter/bluetooth_test.h @@ -29,10 +29,46 @@ #include <map> #include <string> -#include "osi/include/semaphore.h" #include "service/hal/bluetooth_interface.h" #include "types/raw_address.h" +#include <mutex> +#include <condition_variable> + +class btsemaphore { + public: + void post() { + std::lock_guard<std::mutex> lock(mMutex); + ++mCount; + mCondition.notify_one(); + } + + void wait() { + std::unique_lock<std::mutex> lock(mMutex); + while (!mCount) { + mCondition.wait(lock); + } + --mCount; + } + + bool try_wait() { + std::lock_guard<std::mutex> lock(mMutex); + if (mCount) { + --mCount; + return true; + } + return false; + } + + private: + std::mutex mMutex; + std::condition_variable mCondition; + unsigned long mCount = 0; +}; +void semaphore_wait(btsemaphore &s); +void semaphore_post(btsemaphore &s); +void semaphore_try_wait(btsemaphore &s); + namespace bttest { // This class represents the Bluetooth testing framework and provides @@ -73,7 +109,7 @@ class BluetoothTest : public ::testing::Test, bt_bond_state_t GetBondState(); // Reset a semaphores count to 0 - void ClearSemaphore(semaphore_t* sem); + void ClearSemaphore(btsemaphore& sem); // SetUp initializes the Bluetooth interface and registers the callbacks // before running every test @@ -100,10 +136,10 @@ class BluetoothTest : public ::testing::Test, // Semaphores used to wait for specific callback execution. Each callback // has its own semaphore associated with it. - semaphore_t* adapter_properties_callback_sem_; - semaphore_t* remote_device_properties_callback_sem_; - semaphore_t* adapter_state_changed_callback_sem_; - semaphore_t* discovery_state_changed_callback_sem_; + btsemaphore adapter_properties_callback_sem_; + btsemaphore remote_device_properties_callback_sem_; + btsemaphore adapter_state_changed_callback_sem_; + btsemaphore discovery_state_changed_callback_sem_; private: // The bluetooth interface that all the tests use to interact with the HAL diff --git a/system/test/suite/gatt/gatt_test.cc b/system/test/suite/gatt/gatt_test.cc index ef0e5d62e2600b14750f6cf2bf3e54a9f85cce12..68cb2f77af982ff8ff208eb27b8634f650578cf3 100644 --- a/system/test/suite/gatt/gatt_test.cc +++ b/system/test/suite/gatt/gatt_test.cc @@ -40,14 +40,6 @@ void GattTest::SetUp() { semaphore_wait(adapter_state_changed_callback_sem_); EXPECT_TRUE(GetState() == BT_STATE_ON); - register_client_callback_sem_ = semaphore_new(0); - scan_result_callback_sem_ = semaphore_new(0); - - register_server_callback_sem_ = semaphore_new(0); - service_added_callback_sem_ = semaphore_new(0); - service_stopped_callback_sem_ = semaphore_new(0); - service_deleted_callback_sem_ = semaphore_new(0); - bluetooth::hal::BluetoothGattInterface::Initialize(); ASSERT_TRUE(bluetooth::hal::BluetoothGattInterface::IsInitialized()); auto gatt_interface = bluetooth::hal::BluetoothGattInterface::Get(); @@ -65,14 +57,6 @@ void GattTest::TearDown() { gatt_client_interface_ = nullptr; gatt_server_interface_ = nullptr; - semaphore_free(register_client_callback_sem_); - semaphore_free(scan_result_callback_sem_); - - semaphore_free(register_server_callback_sem_); - semaphore_free(service_added_callback_sem_); - semaphore_free(service_stopped_callback_sem_); - semaphore_free(service_deleted_callback_sem_); - bluetooth::hal::BluetoothGattInterface::CleanUp(); ASSERT_EQ(bt_interface()->disable(), BT_STATUS_SUCCESS); diff --git a/system/test/suite/gatt/gatt_test.h b/system/test/suite/gatt/gatt_test.h index da0d6d218c3b7ced4124218397b74fc3c7929905..2704030c9a824924eca2cd4cebcd9957a3fa36a6 100644 --- a/system/test/suite/gatt/gatt_test.h +++ b/system/test/suite/gatt/gatt_test.h @@ -85,17 +85,17 @@ class GattTest : public BluetoothTest, // Semaphores used to wait for specific callback execution. Each callback // has its own semaphore associated with it - semaphore_t* register_client_callback_sem_; - semaphore_t* scan_result_callback_sem_; - semaphore_t* listen_callback_sem_; - - semaphore_t* register_server_callback_sem_; - semaphore_t* service_added_callback_sem_; - semaphore_t* characteristic_added_callback_sem_; - semaphore_t* descriptor_added_callback_sem_; - semaphore_t* service_started_callback_sem_; - semaphore_t* service_stopped_callback_sem_; - semaphore_t* service_deleted_callback_sem_; + btsemaphore register_client_callback_sem_; + btsemaphore scan_result_callback_sem_; + btsemaphore listen_callback_sem_; + + btsemaphore register_server_callback_sem_; + btsemaphore service_added_callback_sem_; + btsemaphore characteristic_added_callback_sem_; + btsemaphore descriptor_added_callback_sem_; + btsemaphore service_started_callback_sem_; + btsemaphore service_stopped_callback_sem_; + btsemaphore service_deleted_callback_sem_; private: // The btgatt_scanner_interface_t that all the tests use to interact with the