1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "invoker_factory.h"
17 
18 #include <memory>
19 #include <utility>
20 
21 #include "__mutex_base"
22 #include "functional"
23 #include "iremote_invoker.h"
24 #include "unordered_map"
25 
26 namespace OHOS {
27 #ifdef CONFIG_IPC_SINGLE
28 namespace IPC_SINGLE {
29 #endif
30 std::atomic<bool> InvokerFactory::isAvailable_ = true;
31 
InvokerFactory()32 InvokerFactory::InvokerFactory() {}
33 
~InvokerFactory()34 InvokerFactory::~InvokerFactory()
35 {
36     std::lock_guard<std::mutex> lockGuard(factoryMutex_);
37     isAvailable_ = false;
38     creators_.clear();
39 }
40 
Get()41 InvokerFactory &InvokerFactory::Get()
42 {
43     static InvokerFactory instance;
44     return instance;
45 }
46 
Register(int protocol,InvokerCreator creator)47 bool InvokerFactory::Register(int protocol, InvokerCreator creator)
48 {
49     if (isAvailable_ != true) {
50         return false;
51     }
52     std::lock_guard<std::mutex> lockGuard(factoryMutex_);
53 
54     /* check isAvailable_ == true again when a thread take mutex */
55     if (isAvailable_ != true) {
56         return false;
57     }
58     return creators_.insert(std::make_pair(protocol, creator)).second;
59 }
60 
Unregister(int protocol)61 void InvokerFactory::Unregister(int protocol)
62 {
63     if (isAvailable_ != true) {
64         return;
65     }
66     std::lock_guard<std::mutex> lockGuard(factoryMutex_);
67 
68     /* check isAvailable_ == true again when a thread take mutex */
69     if (isAvailable_ != true) {
70         return;
71     }
72     (void)creators_.erase(protocol);
73 }
74 
newInstance(int protocol)75 IRemoteInvoker *InvokerFactory::newInstance(int protocol)
76 {
77     if (isAvailable_ != true) {
78         return nullptr;
79     }
80     std::lock_guard<std::mutex> lockGuard(factoryMutex_);
81 
82     /* check isAvailable_ == true again when a thread take mutex */
83     if (isAvailable_ != true) {
84         return nullptr;
85     }
86     auto it = creators_.find(protocol);
87     if (it != creators_.end() && (it->second != nullptr)) {
88         return it->second();
89     }
90     return nullptr;
91 }
92 #ifdef CONFIG_IPC_SINGLE
93 } // namespace IPC_SINGLE
94 #endif
95 } // namespace OHOS