source: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/refcount.h@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 5.0 KB
Line 
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4
5/*this header contains macros for ref_counting a variable.
6
7There are no upper bound checks related to uint32_t overflow because we expect that bigger issues are in
8the system when more than 4 billion references exist to the same variable. In the case when such an overflow
9occurs, the object's ref count will reach zero (while still having 0xFFFFFFFF references) and likely the
10controlling code will take the decision to free the object's resources. Then, any of the 0xFFFFFFFF references
11will interact with deallocated memory / resources resulting in an undefined behavior.
12*/
13
14#ifndef REFCOUNT_H
15#define REFCOUNT_H
16
17#ifdef __cplusplus
18#include <cstdlib>
19#include <cstdint>
20#else
21#include <stdlib.h>
22#include <stdint.h>
23#endif
24
25#include "azure_c_shared_utility/gballoc.h"
26#include "azure_macro_utils/macro_utils.h"
27
28// Include the platform-specific file that defines atomic functionality
29#include "refcount_os.h"
30
31#ifdef __cplusplus
32extern "C"
33{
34#endif
35
36#define REFCOUNT_TYPE(type) \
37struct MU_C2(MU_C2(REFCOUNT_, type), _TAG)
38
39#define REFCOUNT_SHORT_TYPE(type) \
40MU_C2(REFCOUNT_, type)
41
42#define REFCOUNT_TYPE_DECLARE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)
43#define REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)
44#define REFCOUNT_TYPE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)()
45#define REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(type, size) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)(size)
46#define REFCOUNT_TYPE_DECLARE_DESTROY(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)
47#define REFCOUNT_TYPE_DESTROY(type, var) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)(var)
48
49/*this introduces a new refcount'd type based on another type */
50/*and an initializer for that new type that also sets the ref count to 1. The type must not have a flexible array*/
51/*the newly allocated memory shall be free'd by free()*/
52/*and the ref counting is handled internally by the type in the _Create/ _Create_With_Extra_Size /_Clone /_Destroy functions */
53
54/* Codes_SRS_REFCOUNT_01_005: [ REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall allocate memory for the type that is ref counted (type) plus extra memory enough to hold size bytes. ]*/
55/* Codes_SRS_REFCOUNT_01_006: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
56/* Codes_SRS_REFCOUNT_01_007: [ If any error occurs, REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall return NULL. ]*/
57#define DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
58static type* REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(size_t size) \
59{ \
60 REFCOUNT_TYPE(type)* ref_counted = (REFCOUNT_TYPE(type)*)malloc(sizeof(REFCOUNT_TYPE(type)) + size); \
61 type* result; \
62 if (ref_counted == NULL) \
63 { \
64 result = NULL; \
65 } \
66 else \
67 { \
68 result = &ref_counted->counted; \
69 INIT_REF(type, result); \
70 } \
71 return result; \
72} \
73
74/* Codes_SRS_REFCOUNT_01_002: [ REFCOUNT_TYPE_CREATE shall allocate memory for the type that is ref counted. ]*/
75/* Codes_SRS_REFCOUNT_01_003: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
76/* Codes_SRS_REFCOUNT_01_004: [ If any error occurs, REFCOUNT_TYPE_CREATE shall return NULL. ]*/
77#define DEFINE_CREATE(type) \
78static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \
79{ \
80 return REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(0); \
81} \
82
83/* Codes_SRS_REFCOUNT_01_008: [ REFCOUNT_TYPE_DESTROY shall free the memory allocated by REFCOUNT_TYPE_CREATE or REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE. ]*/
84/* Codes_SRS_REFCOUNT_01_009: [ If counted_type is NULL, REFCOUNT_TYPE_DESTROY shall return. ]*/
85#define DEFINE_DESTROY(type) \
86static void REFCOUNT_TYPE_DECLARE_DESTROY(type)(type* counted_type) \
87{ \
88 void* ref_counted = (void*)((unsigned char*)counted_type - offsetof(REFCOUNT_TYPE(type), counted)); \
89 free(ref_counted); \
90}
91
92#define DEFINE_REFCOUNT_TYPE(type) \
93REFCOUNT_TYPE(type) \
94{ \
95 COUNT_TYPE count; \
96 type counted; \
97}; \
98DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
99DEFINE_CREATE(type) \
100DEFINE_DESTROY(type) \
101
102#ifndef DEC_RETURN_ZERO
103#error refcount_os.h does not define DEC_RETURN_ZERO
104#endif // !DEC_RETURN_ZERO
105#ifndef INC_REF_VAR
106#error refcount_os.h does not define INC_REF_VAR
107#endif // !INC_REF
108#ifndef DEC_REF_VAR
109#error refcount_os.h does not define DEC_REF_VAR
110#endif // !DEC_REF
111#ifndef INIT_REF_VAR
112#error refcount_os.h does not define INIT_REF_VAR
113#endif // !INIT_REF
114
115#define INC_REF(type, var) INC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
116#define DEC_REF(type, var) DEC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
117#define INIT_REF(type, var) INIT_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
118
119#ifdef __cplusplus
120}
121#endif
122
123#endif /*REFCOUNT_H*/
124
125
Note: See TracBrowser for help on using the repository browser.