Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc3bcda5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Test: Stability improvements on bluetooth_stack_with_facade" into tm-dev

parents 84cd9ab5 17d6aef7
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -51,13 +51,15 @@ extern "C" const char* __asan_default_options() {
namespace {
::bluetooth::facade::GrpcRootServer grpc_root_server;

std::promise<void> interrupt_promise;
std::future<void> interrupt_future;
bool interrupted = false;
struct sigaction old_act = {};
void interrupt_handler(int signal_number) {
  if (!interrupted) {
    interrupted = true;
    LOG_INFO("Stopping gRPC root server due to signal: %s[%d]", strsignal(signal_number), signal_number);
    grpc_root_server.StopServer();
    interrupt_promise.set_value();
  } else {
    LOG_WARN("Already interrupted by signal: %s[%d]", strsignal(signal_number), signal_number);
  }
@@ -94,6 +96,15 @@ bool crash_callback(const void* crash_context, size_t crash_context_size, void*
  return true;
}

// Need to stop server on a thread that is not part of a signal handler due to an issue with gRPC
// See: https://github.com/grpc/grpc/issues/24884
void thread_check_shutdown() {
  LOG_INFO("shutdown thread waiting for interruption");
  interrupt_future.wait();
  LOG_INFO("interrupted, stopping server");
  grpc_root_server.StopServer();
}

}  // namespace

// The entry point for the binary with libbluetooth + facades
@@ -148,9 +159,16 @@ int main(int argc, const char** argv) {
    LOG_ERROR("sigaction error: %s", strerror(errno));
  }

  LOG_INFO("Starting Server");
  grpc_root_server.StartServer("0.0.0.0", root_server_port, grpc_port);
  LOG_INFO("Server started");
  auto wait_thread = std::thread([] { grpc_root_server.RunGrpcLoop(); });
  interrupt_future = interrupt_promise.get_future();
  auto shutdown_thread = std::thread{thread_check_shutdown};
  wait_thread.join();
  LOG_INFO("Server terminated");
  shutdown_thread.join();
  LOG_INFO("Shutdown thread terminated");

  return 0;
}
+29 −35
Original line number Diff line number Diff line
@@ -29,26 +29,15 @@
#include "hci/facade/le_advertising_manager_facade.h"
#include "hci/facade/le_initiator_address_facade.h"
#include "hci/facade/le_scanning_manager_facade.h"
#include "hci/hci_layer.h"
#include "hci/le_advertising_manager.h"
#include "hci/le_scanning_manager.h"
#include "iso/facade.h"
#include "l2cap/classic/facade.h"
#include "l2cap/le/facade.h"
#include "neighbor/connectability.h"
#include "neighbor/discoverability.h"
#include "neighbor/facade/facade.h"
#include "neighbor/inquiry.h"
#include "neighbor/name.h"
#include "neighbor/page.h"
#include "os/log.h"
#include "os/thread.h"
#include "security/facade.h"
#include "security/security_module.h"
#include "shim/dumpsys.h"
#include "shim/facade/facade.h"
#include "stack_manager.h"
#include "storage/storage_module.h"

namespace bluetooth {
namespace facade {
@@ -57,10 +46,9 @@ using ::blueberry::facade::BluetoothModule;
using ::bluetooth::grpc::GrpcModule;
using ::bluetooth::os::Thread;

namespace {
class RootFacadeService : public ::blueberry::facade::RootFacade::Service {
 public:
  RootFacadeService(int grpc_port) : grpc_port_(grpc_port) {}
  explicit RootFacadeService(int grpc_port) : grpc_port_(grpc_port) {}

  ::grpc::Status StartStack(
      ::grpc::ServerContext* context,
@@ -123,13 +111,13 @@ class RootFacadeService : public ::blueberry::facade::RootFacade::Service {
        return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "invalid module under test");
    }

    stack_thread_ = new Thread("stack_thread", Thread::Priority::NORMAL);
    stack_manager_.StartUp(&modules, stack_thread_);
    stack_thread_ = std::make_unique<Thread>("stack_thread", Thread::Priority::NORMAL);
    stack_manager_.StartUp(&modules, stack_thread_.get());

    GrpcModule* grpc_module = stack_manager_.GetInstance<GrpcModule>();
    grpc_module->StartServer("0.0.0.0", grpc_port_);

    grpc_loop_thread_ = new std::thread([grpc_module] { grpc_module->RunGrpcLoop(); });
    grpc_loop_thread_ = std::make_unique<std::thread>([grpc_module] { grpc_module->RunGrpcLoop(); });
    is_running_ = true;

    return ::grpc::Status::OK;
@@ -145,50 +133,56 @@ class RootFacadeService : public ::blueberry::facade::RootFacade::Service {

    stack_manager_.GetInstance<GrpcModule>()->StopServer();
    grpc_loop_thread_->join();
    delete grpc_loop_thread_;
    grpc_loop_thread_.reset();

    stack_manager_.ShutDown();
    delete stack_thread_;
    stack_thread_.reset();
    is_running_ = false;
    return ::grpc::Status::OK;
  }

 private:
  Thread* stack_thread_ = nullptr;
  std::unique_ptr<Thread> stack_thread_ = nullptr;
  bool is_running_ = false;
  std::thread* grpc_loop_thread_ = nullptr;
  std::unique_ptr<std::thread> grpc_loop_thread_ = nullptr;
  StackManager stack_manager_;
  int grpc_port_ = 8898;
};

RootFacadeService* root_facade_service;
}  // namespace
struct GrpcRootServer::impl {
  bool started_ = false;
  std::unique_ptr<RootFacadeService> root_facade_service_ = nullptr;
  std::unique_ptr<::grpc::Server> server_ = nullptr;
};

GrpcRootServer::GrpcRootServer() : pimpl_(new impl()) {}

GrpcRootServer::~GrpcRootServer() = default;

void GrpcRootServer::StartServer(const std::string& address, int grpc_root_server_port, int grpc_port) {
  ASSERT(!started_);
  started_ = true;
  ASSERT(!pimpl_->started_);
  pimpl_->started_ = true;

  std::string listening_port = address + ":" + std::to_string(grpc_root_server_port);
  ::grpc::ServerBuilder builder;
  root_facade_service = new RootFacadeService(grpc_port);
  builder.RegisterService(root_facade_service);

  pimpl_->root_facade_service_ = std::make_unique<RootFacadeService>(grpc_port);
  builder.RegisterService(pimpl_->root_facade_service_.get());
  builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
  server_ = builder.BuildAndStart();
  pimpl_->server_ = builder.BuildAndStart();

  ASSERT(server_ != nullptr);
  ASSERT(pimpl_->server_ != nullptr);
}

void GrpcRootServer::StopServer() {
  ASSERT(started_);
  server_->Shutdown();
  started_ = false;
  server_.reset();
  delete root_facade_service;
  ASSERT(pimpl_->started_);
  pimpl_->server_->Shutdown();
  pimpl_->started_ = false;
}

void GrpcRootServer::RunGrpcLoop() {
  ASSERT(started_);
  server_->Wait();
  ASSERT(pimpl_->started_);
  pimpl_->server_->Wait();
}

}  // namespace facade
+5 −2
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ namespace facade {

class GrpcRootServer {
 public:
  GrpcRootServer();
  ~GrpcRootServer();

  void StartServer(const std::string& address, int grpc_root_server_port, int grpc_port);

  void StopServer();
@@ -33,8 +36,8 @@ class GrpcRootServer {
  void RunGrpcLoop();

 private:
  bool started_ = false;
  std::unique_ptr<::grpc::Server> server_ = nullptr;
  struct impl;
  std::unique_ptr<impl> pimpl_;
};

}  // namespace facade
+1 −0
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service, public Connect
    std::unique_lock<std::mutex> lock(acl_connections_mutex_);
    std::shared_ptr<ClassicAclConnection> shared_connection = std::move(connection);
    uint16_t handle = to_handle(current_connection_request_);
    acl_connections_.erase(handle);
    acl_connections_.emplace(
        std::piecewise_construct,
        std::forward_as_tuple(handle),