1 /* 2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3 * 4 * HDF is dual licensed: you can use it either under the terms of 5 * the GPL, or the BSD license, at your option. 6 * See the LICENSE file in the root of this repository for complete details. 7 */ 8 #ifndef SHARED_OBJ_H 9 #define SHARED_OBJ_H 10 11 #include "osal_atomic.h" 12 #include "osal_mem.h" 13 14 #define SHARED_OBJ(OBJ_TYPE) enum MessageEngineStatus status; \ 15 OsalAtomic refCount; \ 16 struct OBJ_TYPE *(*Ref)(struct OBJ_TYPE * obj); \ 17 void (*Disref)(struct OBJ_TYPE * obj); \ 18 void (*Destroy)(struct OBJ_TYPE * obj) 19 20 #define DECLEAR_SHARED_OBJ_FUNC(OBJ_TYPE) \ 21 struct OBJ_TYPE *Reference##OBJ_TYPE(struct OBJ_TYPE *obj); \ 22 void Disreference##OBJ_TYPE(struct OBJ_TYPE *obj); \ 23 ErrorCode InitSharedObj##OBJ_TYPE(struct OBJ_TYPE *obj, void (*Destroy)(struct OBJ_TYPE *)); \ 24 void DeinitSharedObj##OBJ_TYPE(struct OBJ_TYPE *obj) 25 26 #define IMPLEMENT_SHARED_OBJ(OBJ_TYPE) \ 27 struct OBJ_TYPE *Reference##OBJ_TYPE(struct OBJ_TYPE *obj) \ 28 { \ 29 if (obj == NULL) { \ 30 return NULL; \ 31 } \ 32 if (obj->status > ME_STATUS_RUNNING) { \ 33 return NULL; \ 34 } \ 35 struct OBJ_TYPE *result = NULL; \ 36 if (obj->status <= ME_STATUS_RUNNING && OsalAtomicRead(&obj->refCount) < MAX_OBJ_REF_COUNT) { \ 37 OsalAtomicInc(&obj->refCount); \ 38 result = obj; \ 39 } \ 40 return result; \ 41 } \ 42 void Disreference##OBJ_TYPE(struct OBJ_TYPE *obj) \ 43 { \ 44 if (obj == NULL) { \ 45 return; \ 46 } \ 47 OsalAtomicDec(&obj->refCount); \ 48 if (OsalAtomicRead(&obj->refCount) <= 0) { \ 49 obj->status = ME_STATUS_TODESTROY; \ 50 if (obj->Destroy != NULL) { \ 51 obj->Destroy(obj); \ 52 OsalMemFree(obj); \ 53 } \ 54 } \ 55 } \ 56 ErrorCode InitSharedObj##OBJ_TYPE(struct OBJ_TYPE *obj, void (*Destroy)(struct OBJ_TYPE *)) \ 57 { \ 58 if (Destroy == NULL) { \ 59 return ME_ERROR_NULL_PTR; \ 60 } \ 61 OsalAtomicSet(&obj->refCount, 1); \ 62 obj->Ref = Reference##OBJ_TYPE; \ 63 obj->Disref = Disreference##OBJ_TYPE; \ 64 obj->Destroy = Destroy; \ 65 return ME_SUCCESS; \ 66 } \ 67 void DeinitSharedObj##OBJ_TYPE(struct OBJ_TYPE *obj) \ 68 { \ 69 if (obj != NULL) { \ 70 OsalAtomicSet(&obj->refCount, 0); \ 71 } \ 72 } 73 74 #define INIT_SHARED_OBJ(OBJ_TYPE, obj, DestroyFunc) InitSharedObj##OBJ_TYPE(obj, DestroyFunc) 75 #define DEINIT_SHARED_OBJ(OBJ_TYPE, obj) DeinitSharedObj##OBJ_TYPE(obj) 76 77 78 #endif 79