1 /*
2  * Copyright (c) 2020 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 #include "client_factory.h"
16 #include <ohos_errno.h>
17 #include "registry.h"
18 #include "memory_adapter.h"
19 #include "thread_adapter.h"
20 #include "default_client.h"
21 
22 typedef struct Factory Factory;
23 struct Factory {
24     SaName key;
25     Creator creator;
26     Destroyer destroyer;
27 };
28 
29 static Vector g_factories;
30 static MutexId g_mutex;
31 static Factory *GetFactory(const char *service, const char *feature);
32 
SAMGR_CreateIClient(const char * service,const char * feature,uint32 size)33 void *SAMGR_CreateIClient(const char *service, const char *feature, uint32 size)
34 {
35     if (service == NULL) {
36         return NULL;
37     }
38 
39     if (g_mutex == NULL) {
40         return NULL;
41     }
42 
43     Factory *factory = GetFactory(service, feature);
44     if (factory == NULL) {
45         return NULL;
46     }
47 
48     return factory->creator(service, feature, size);
49 }
50 
SAMGR_ReleaseIClient(const char * service,const char * feature,void * iClient)51 int SAMGR_ReleaseIClient(const char *service, const char *feature, void *iClient)
52 {
53     if (service == NULL || iClient == NULL) {
54         return EC_INVALID;
55     }
56 
57     if (g_mutex == NULL) {
58         return EC_NOHANDLER;
59     }
60 
61     Factory *factory = GetFactory(service, feature);
62     if (factory == NULL) {
63         return EC_NOHANDLER;
64     }
65     factory->destroyer(service, feature, iClient);
66     return EC_SUCCESS;
67 }
68 
SAMGR_RegisterFactory(const char * service,const char * feature,Creator creator,Destroyer destroyer)69 int SAMGR_RegisterFactory(const char *service, const char *feature, Creator creator, Destroyer destroyer)
70 {
71     if (service == NULL || creator == NULL || destroyer == NULL) {
72         return EC_INVALID;
73     }
74 
75     if (g_mutex == NULL) {
76         g_factories = VECTOR_Make(NULL, (VECTOR_Compare)SAMGR_CompareSAName);
77         g_mutex = MUTEX_InitValue();
78         if (g_mutex == NULL) {
79             return EC_NOMEMORY;
80         }
81     }
82 
83     Factory *factory = GetFactory(service, feature);
84     if (factory != NULL) {
85         return EC_SUCCESS;
86     }
87 
88     MUTEX_Lock(g_mutex);
89     factory = SAMGR_Malloc(sizeof(Factory));
90     if (factory == NULL) {
91         MUTEX_Unlock(g_mutex);
92         return EC_NOMEMORY;
93     }
94     factory->key.service = service;
95     factory->key.feature = feature;
96     factory->creator = creator;
97     factory->destroyer = destroyer;
98     int ret = VECTOR_Add(&g_factories, factory);
99     MUTEX_Unlock(g_mutex);
100     if (ret == INVALID_INDEX) {
101         SAMGR_Free(factory);
102         return EC_NOMEMORY;
103     }
104     return EC_SUCCESS;
105 }
106 
GetFactory(const char * service,const char * feature)107 static Factory *GetFactory(const char *service, const char *feature)
108 {
109     SaName key = {service, feature};
110     Factory *factory = NULL;
111     MUTEX_Lock(g_mutex);
112     int16 index = VECTOR_FindByKey(&g_factories, &key);
113     if (index != INVALID_INDEX) {
114         factory = VECTOR_At(&g_factories, index);
115     }
116     MUTEX_Unlock(g_mutex);
117     return factory;
118 }
119