Home | History | Annotate | Download | only in lib
      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