source: azure_iot_hub/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/refcount.h@ 389

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

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 4.9 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#include "azure_c_shared_utility/gballoc.h"
18#include "azure_c_shared_utility/macro_utils.h"
19
20#ifdef __cplusplus
21#include <cstdlib>
22#include <cstdint>
23extern "C"
24{
25#else
26#include <stdlib.h>
27#include <stdint.h>
28#endif
29
30// Include the platform-specific file that defines atomic functionality
31#include "refcount_os.h"
32
33#define REFCOUNT_TYPE(type) \
34struct MU_C2(MU_C2(REFCOUNT_, type), _TAG)
35
36#define REFCOUNT_SHORT_TYPE(type) \
37MU_C2(REFCOUNT_, type)
38
39#define REFCOUNT_TYPE_DECLARE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)
40#define REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)
41#define REFCOUNT_TYPE_CREATE(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create)()
42#define REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(type, size) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)(size)
43#define REFCOUNT_TYPE_DECLARE_DESTROY(type) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)
44#define REFCOUNT_TYPE_DESTROY(type, var) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)(var)
45
46/*this introduces a new refcount'd type based on another type */
47/*and an initializer for that new type that also sets the ref count to 1. The type must not have a flexible array*/
48/*the newly allocated memory shall be free'd by free()*/
49/*and the ref counting is handled internally by the type in the _Create/ _Create_With_Extra_Size /_Clone /_Destroy functions */
50
51/* 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. ]*/
52/* Codes_SRS_REFCOUNT_01_006: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
53/* Codes_SRS_REFCOUNT_01_007: [ If any error occurs, REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall return NULL. ]*/
54#define DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
55static type* REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(size_t size) \
56{ \
57 REFCOUNT_TYPE(type)* ref_counted = (REFCOUNT_TYPE(type)*)malloc(sizeof(REFCOUNT_TYPE(type)) + size); \
58 type* result; \
59 if (ref_counted == NULL) \
60 { \
61 result = NULL; \
62 } \
63 else \
64 { \
65 result = &ref_counted->counted; \
66 INIT_REF(type, result); \
67 } \
68 return result; \
69} \
70
71/* Codes_SRS_REFCOUNT_01_002: [ REFCOUNT_TYPE_CREATE shall allocate memory for the type that is ref counted. ]*/
72/* Codes_SRS_REFCOUNT_01_003: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
73/* Codes_SRS_REFCOUNT_01_004: [ If any error occurs, REFCOUNT_TYPE_CREATE shall return NULL. ]*/
74#define DEFINE_CREATE(type) \
75static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \
76{ \
77 return REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(0); \
78} \
79
80/* Codes_SRS_REFCOUNT_01_008: [ REFCOUNT_TYPE_DESTROY shall free the memory allocated by REFCOUNT_TYPE_CREATE or REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE. ]*/
81/* Codes_SRS_REFCOUNT_01_009: [ If counted_type is NULL, REFCOUNT_TYPE_DESTROY shall return. ]*/
82#define DEFINE_DESTROY(type) \
83static void REFCOUNT_TYPE_DECLARE_DESTROY(type)(type* counted_type) \
84{ \
85 void* ref_counted = (void*)((unsigned char*)counted_type - offsetof(REFCOUNT_TYPE(type), counted)); \
86 free(ref_counted); \
87}
88
89#define DEFINE_REFCOUNT_TYPE(type) \
90REFCOUNT_TYPE(type) \
91{ \
92 COUNT_TYPE count; \
93 type counted; \
94}; \
95DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
96DEFINE_CREATE(type) \
97DEFINE_DESTROY(type) \
98
99#ifndef DEC_RETURN_ZERO
100#error refcount_os.h does not define DEC_RETURN_ZERO
101#endif // !DEC_RETURN_ZERO
102#ifndef INC_REF_VAR
103#error refcount_os.h does not define INC_REF_VAR
104#endif // !INC_REF
105#ifndef DEC_REF_VAR
106#error refcount_os.h does not define DEC_REF_VAR
107#endif // !DEC_REF
108#ifndef INIT_REF_VAR
109#error refcount_os.h does not define INIT_REF_VAR
110#endif // !INIT_REF
111
112#define INC_REF(type, var) INC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
113#define DEC_REF(type, var) DEC_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
114#define INIT_REF(type, var) INIT_REF_VAR(((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
115
116#ifdef __cplusplus
117}
118#endif
119
120#endif /*REFCOUNT_H*/
121
122
Note: See TracBrowser for help on using the repository browser.