1 #pragma once 2 3 /* 4 * Copyright (C) 2017 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 // Object that represents a region on the Host 20 21 #include "common/vsoc/lib/region_view.h" 22 23 #include <map> 24 #include <mutex> 25 #include <string> 26 27 namespace vsoc { 28 29 /** 30 * This class adds methods that depend on the Region's type. 31 * This may be directly constructed. However, it may be more effective to 32 * subclass it, adding region-specific methods. 33 * 34 * Layout should be VSoC shared memory compatible, defined in common/vsoc/shm, 35 * and should have a constant string region name. 36 */ 37 template <typename ViewType, typename LayoutType> 38 class TypedRegionView : public RegionView { 39 public: 40 using Layout = LayoutType; 41 42 /* Returns a pointer to the region with a type that matches the layout */ 43 LayoutType* data() { 44 return this->GetLayoutPointer<LayoutType>(); 45 } 46 47 const LayoutType& data() const { 48 return this->region_offset_to_reference<LayoutType>( 49 control_->region_desc().offset_of_region_data); 50 } 51 52 protected: 53 #if defined(CUTTLEFISH_HOST) 54 bool Open(const char* domain) { 55 return RegionView::Open(LayoutType::region_name, domain); 56 } 57 #else 58 bool Open() { 59 return RegionView::Open(LayoutType::region_name); 60 } 61 #endif 62 63 public: 64 // Implementation of the region singletons. 65 #if defined(CUTTLEFISH_HOST) 66 static ViewType* GetInstance(const char* domain) { 67 static std::mutex mtx; 68 static std::map<std::string, std::unique_ptr<ViewType>> instances; 69 if (!domain) { 70 return nullptr; 71 } 72 std::lock_guard<std::mutex> lock(mtx); 73 // Get a reference to the actual unique_ptr that's stored in the map, if 74 // there wasn't one it will be default constructed pointing to nullptr. 75 auto& instance = instances[domain]; 76 if (!instance) { 77 // Update the referenced pointer with the address of the newly created 78 // region view. 79 instance.reset(new ViewType{}); 80 if (!instance->Open(domain)) { 81 instance.reset(); 82 } 83 } 84 return instance.get(); 85 } 86 #else 87 static ViewType* GetInstance() { 88 static std::mutex mtx; 89 static std::unique_ptr<ViewType> instance; 90 std::lock_guard<std::mutex> lock(mtx); 91 if (!instance) { 92 instance.reset(new ViewType{}); 93 if (!instance->Open()) { 94 instance.reset(); 95 } 96 } 97 return instance.get(); 98 } 99 #endif 100 101 102 }; 103 104 } // namespace vsoc 105