1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "module.h" 18 19 using ::bluetooth::os::Handler; 20 using ::bluetooth::os::Thread; 21 22 namespace bluetooth { 23 24 constexpr std::chrono::milliseconds kModuleStopTimeout = std::chrono::milliseconds(20); 25 26 ModuleFactory::ModuleFactory(std::function<Module*()> ctor) : ctor_(ctor) { 27 } 28 29 std::string Module::ToString() const { 30 return "Module"; 31 } 32 33 Handler* Module::GetHandler() const { 34 ASSERT_LOG(handler_ != nullptr, "Can't get handler when it's not started"); 35 return handler_; 36 } 37 38 const ModuleRegistry* Module::GetModuleRegistry() const { 39 return registry_; 40 } 41 42 Module* Module::GetDependency(const ModuleFactory* module) const { 43 for (auto& dependency : dependencies_.list_) { 44 if (dependency == module) { 45 return registry_->Get(module); 46 } 47 } 48 49 ASSERT_LOG(false, "Module was not listed as a dependency in ListDependencies"); 50 } 51 52 Module* ModuleRegistry::Get(const ModuleFactory* module) const { 53 auto instance = started_modules_.find(module); 54 ASSERT(instance != started_modules_.end()); 55 return instance->second; 56 } 57 58 bool ModuleRegistry::IsStarted(const ModuleFactory* module) const { 59 return started_modules_.find(module) != started_modules_.end(); 60 } 61 62 void ModuleRegistry::Start(ModuleList* modules, Thread* thread) { 63 for (auto it = modules->list_.begin(); it != modules->list_.end(); it++) { 64 Start(*it, thread); 65 } 66 } 67 68 void ModuleRegistry::set_registry_and_handler(Module* instance, Thread* thread) const { 69 instance->registry_ = this; 70 instance->handler_ = new Handler(thread); 71 } 72 73 Module* ModuleRegistry::Start(const ModuleFactory* module, Thread* thread) { 74 auto started_instance = started_modules_.find(module); 75 if (started_instance != started_modules_.end()) { 76 return started_instance->second; 77 } 78 79 Module* instance = module->ctor_(); 80 set_registry_and_handler(instance, thread); 81 82 instance->ListDependencies(&instance->dependencies_); 83 Start(&instance->dependencies_, thread); 84 85 instance->Start(); 86 start_order_.push_back(module); 87 started_modules_[module] = instance; 88 return instance; 89 } 90 91 void ModuleRegistry::StopAll() { 92 // Since modules were brought up in dependency order, it is safe to tear down by going in reverse order. 93 for (auto it = start_order_.rbegin(); it != start_order_.rend(); it++) { 94 auto instance = started_modules_.find(*it); 95 ASSERT(instance != started_modules_.end()); 96 97 // Clear the handler before stopping the module to allow it to shut down gracefully. 98 instance->second->handler_->Clear(); 99 instance->second->handler_->WaitUntilStopped(kModuleStopTimeout); 100 instance->second->Stop(); 101 102 delete instance->second->handler_; 103 delete instance->second; 104 started_modules_.erase(instance); 105 } 106 107 ASSERT(started_modules_.empty()); 108 start_order_.clear(); 109 } 110 111 os::Handler* ModuleRegistry::GetModuleHandler(const ModuleFactory* module) const { 112 auto started_instance = started_modules_.find(module); 113 if (started_instance != started_modules_.end()) { 114 return started_instance->second->GetHandler(); 115 } 116 return nullptr; 117 } 118 } // namespace bluetooth 119