1 /*
2 * Copyright (c) 2025 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 "softbus_rc_object.h"
16
17 #include "comm_log.h"
18
Lock(SoftBusRcObject * object)19 static int32_t Lock(SoftBusRcObject *object)
20 {
21 COMM_CHECK_AND_RETURN_RET_LOGE(object != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "object is null");
22 return SoftBusMutexLock(&object->mutex);
23 }
24
Unlock(SoftBusRcObject * object)25 static void Unlock(SoftBusRcObject *object)
26 {
27 COMM_CHECK_AND_RETURN_LOGE(object != NULL, COMM_UTILS, "object is null");
28 (void)SoftBusMutexUnlock(&object->mutex);
29 }
30
Reference(SoftBusRcObject * object)31 int32_t Reference(SoftBusRcObject *object)
32 {
33 COMM_CHECK_AND_RETURN_RET_LOGE(object != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "object is null");
34
35 int32_t ret = Lock(object);
36 COMM_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, COMM_UTILS,
37 "%{public}s lock fail: id=%{public}d, error=%{public}d", object->name, object->id, ret);
38 object->objectRc += 1;
39 Unlock(object);
40 return SOFTBUS_OK;
41 }
42
Deference(SoftBusRcObject ** ptr)43 void Deference(SoftBusRcObject **ptr)
44 {
45 COMM_CHECK_AND_RETURN_LOGE(ptr != NULL, COMM_UTILS, "ptr is null");
46 SoftBusRcObject *object = *ptr;
47 COMM_CHECK_AND_RETURN_LOGE(object != NULL, COMM_UTILS, "object is null");
48
49 int32_t ret = Lock(object);
50 COMM_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, COMM_UTILS, "%{public}s lock fail: id=%{public}d, error=%{public}d",
51 object->name, object->id, ret);
52 object->objectRc -= 1;
53 int32_t remain = object->objectRc;
54 Unlock(object);
55
56 if (remain <= 0) {
57 COMM_LOGW(COMM_UTILS, "%{public}s is not referenced by anyone, id=%{public}d, object rc=%{public}d",
58 object->name, object->id, object->objectRc);
59 object->freehook(object);
60 }
61 *ptr = NULL;
62 }
63
SoftBusRcObjectConstruct(const char * name,SoftBusRcObject * object,SoftBusRcFreeHook hook)64 int32_t SoftBusRcObjectConstruct(const char *name, SoftBusRcObject *object, SoftBusRcFreeHook hook)
65 {
66 COMM_CHECK_AND_RETURN_RET_LOGE(name != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "name is null");
67 COMM_CHECK_AND_RETURN_RET_LOGE(object != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "object is null");
68 COMM_CHECK_AND_RETURN_RET_LOGE(hook != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "free hook is null");
69
70 ListInit(&object->node);
71 object->id = 0;
72 object->mutex = (SoftBusMutex)0;
73 SoftBusMutexAttr attr = {
74 .type = SOFTBUS_MUTEX_RECURSIVE,
75 };
76 int32_t ret = SoftBusMutexInit(&object->mutex, &attr);
77 COMM_CHECK_AND_RETURN_RET_LOGE(
78 ret == SOFTBUS_OK, ret, COMM_UTILS, "%{public}s init lock fail: error=%{public}d", name, ret);
79 // assigned 1, as object is referenced by local construct progress
80 object->objectRc = 1;
81 object->freehook = hook;
82 object->name = name;
83
84 object->Lock = Lock;
85 object->Unlock = Unlock;
86 object->Reference = Reference;
87 object->Dereference = Deference;
88
89 return SOFTBUS_OK;
90 }
91
SoftBusRcObjectDestruct(SoftBusRcObject * object)92 void SoftBusRcObjectDestruct(SoftBusRcObject *object)
93 {
94 COMM_CHECK_AND_RETURN_LOGE(object != NULL, COMM_UTILS, "object is null");
95
96 ListDelete(&object->node);
97 object->id = 0;
98 (void)SoftBusMutexDestroy(&object->mutex);
99 object->objectRc = 0;
100 object->freehook = NULL;
101 object->name = NULL;
102
103 object->Lock = NULL;
104 object->Unlock = NULL;
105 object->Reference = NULL;
106 object->Dereference = NULL;
107 }