63 |
63 |
64 /* Means: tried but failed to create. */ |
64 /* Means: tried but failed to create. */ |
65 #define HB_SHAPER_DATA_INVALID ((void *) -1) |
65 #define HB_SHAPER_DATA_INVALID ((void *) -1) |
66 #define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID) |
66 #define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID) |
67 |
67 |
68 #define HB_SHAPER_DATA_TYPE(shaper, object) struct hb_##shaper##_shaper_##object##_data_t |
68 #define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_shaper_##object##_data_t |
|
69 #define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object) |
69 #define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper) |
70 #define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper) |
70 #define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE (shaper, object, object) |
71 #define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object) |
71 #define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create |
72 #define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create |
72 #define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy |
73 #define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy |
|
74 #define HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) hb_##shaper##_shaper_##object##_data_ensure |
73 |
75 |
74 #define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \ |
76 #define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \ |
75 HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \ |
77 HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \ |
76 extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \ |
78 extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \ |
77 HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \ |
79 HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \ |
78 extern "C" HB_INTERNAL void \ |
80 extern "C" HB_INTERNAL void \ |
79 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data) |
81 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \ |
|
82 extern "C" HB_INTERNAL bool \ |
|
83 HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object) |
80 |
84 |
81 #define HB_SHAPER_DATA_DESTROY(shaper, object) \ |
85 #define HB_SHAPER_DATA_DESTROY(shaper, object) \ |
82 if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \ |
86 if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \ |
83 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \ |
87 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \ |
84 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); |
88 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); |
85 |
89 |
86 #define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \ |
90 #define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \ |
87 static inline bool \ |
91 HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true) |
88 hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \ |
92 |
|
93 #define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \ |
|
94 bool \ |
|
95 HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \ |
89 {\ |
96 {\ |
90 retry: \ |
97 retry: \ |
91 HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \ |
98 HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \ |
|
99 if (likely (data) && !(condition)) { \ |
|
100 /* Drop and recreate. */ \ |
|
101 /* If someone dropped it in the mean time, throw it away and don't touch it. \ |
|
102 * Otherwise, destruct it. */ \ |
|
103 if (hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), data, nullptr)) { \ |
|
104 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ |
|
105 } \ |
|
106 goto retry; \ |
|
107 } \ |
92 if (unlikely (!data)) { \ |
108 if (unlikely (!data)) { \ |
93 data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \ |
109 data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \ |
94 if (unlikely (!data)) \ |
110 if (unlikely (!data)) \ |
95 data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \ |
111 data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \ |
96 if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \ |
112 if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), nullptr, data)) { \ |
97 if (data && \ |
113 if (data && \ |
98 data != HB_SHAPER_DATA_INVALID && \ |
114 data != HB_SHAPER_DATA_INVALID && \ |
99 data != HB_SHAPER_DATA_SUCCEEDED) \ |
115 data != HB_SHAPER_DATA_SUCCEEDED) \ |
100 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ |
116 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ |
101 goto retry; \ |
117 goto retry; \ |
102 } \ |
118 } \ |
103 } \ |
119 } \ |
104 return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \ |
120 return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \ |
105 } |
121 } |
106 |
122 |
107 |
123 |
108 #endif /* HB_SHAPER_PRIVATE_HH */ |
124 #endif /* HB_SHAPER_PRIVATE_HH */ |