1 /* hazardpointer.c generated by valac 0.46.6, the Vala compiler
2 * generated from hazardpointer.vala, do not modify */
3
4 /* hazardpointer.vala
5 *
6 * Copyright (C) 2011 Maciej Piechotka
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * Author:
23 * Maciej Piechotka <uzytkownik2@gmail.com>
24 */
25
26 #include <glib-object.h>
27 #include <glib.h>
28 #include <free.h>
29 #include <string.h>
30
31 typedef struct _GeeHazardPointer GeeHazardPointer;
32 typedef struct _GeeHazardPointerNode GeeHazardPointerNode;
33 typedef enum {
34 GEE_HAZARD_POINTER_POLICY_DEFAULT,
35 GEE_HAZARD_POINTER_POLICY_THREAD_EXIT,
36 GEE_HAZARD_POINTER_POLICY_TRY_FREE,
37 GEE_HAZARD_POINTER_POLICY_FREE,
38 GEE_HAZARD_POINTER_POLICY_TRY_RELEASE,
39 GEE_HAZARD_POINTER_POLICY_RELEASE
40 } GeeHazardPointerPolicy;
41
42 #define GEE_HAZARD_POINTER_TYPE_POLICY (gee_hazard_pointer_policy_get_type ())
43
44 #define GEE_TYPE_ABSTRACT_COLLECTION (gee_abstract_collection_get_type ())
45 #define GEE_ABSTRACT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection))
46 #define GEE_ABSTRACT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollectionClass))
47 #define GEE_IS_ABSTRACT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_COLLECTION))
48 #define GEE_IS_ABSTRACT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_COLLECTION))
49 #define GEE_ABSTRACT_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollectionClass))
50
51 typedef struct _GeeAbstractCollection GeeAbstractCollection;
52 typedef struct _GeeAbstractCollectionClass GeeAbstractCollectionClass;
53
54 #define GEE_TYPE_ABSTRACT_LIST (gee_abstract_list_get_type ())
55 #define GEE_ABSTRACT_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_LIST, GeeAbstractList))
56 #define GEE_ABSTRACT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_LIST, GeeAbstractListClass))
57 #define GEE_IS_ABSTRACT_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_LIST))
58 #define GEE_IS_ABSTRACT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_LIST))
59 #define GEE_ABSTRACT_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_LIST, GeeAbstractListClass))
60
61 typedef struct _GeeAbstractList GeeAbstractList;
62 typedef struct _GeeAbstractListClass GeeAbstractListClass;
63
64 #define GEE_TYPE_ABSTRACT_BIDIR_LIST (gee_abstract_bidir_list_get_type ())
65 #define GEE_ABSTRACT_BIDIR_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirList))
66 #define GEE_ABSTRACT_BIDIR_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirListClass))
67 #define GEE_IS_ABSTRACT_BIDIR_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST))
68 #define GEE_IS_ABSTRACT_BIDIR_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_BIDIR_LIST))
69 #define GEE_ABSTRACT_BIDIR_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirListClass))
70
71 typedef struct _GeeAbstractBidirList GeeAbstractBidirList;
72 typedef struct _GeeAbstractBidirListClass GeeAbstractBidirListClass;
73
74 #define GEE_TYPE_ARRAY_LIST (gee_array_list_get_type ())
75 #define GEE_ARRAY_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ARRAY_LIST, GeeArrayList))
76 #define GEE_ARRAY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ARRAY_LIST, GeeArrayListClass))
77 #define GEE_IS_ARRAY_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ARRAY_LIST))
78 #define GEE_IS_ARRAY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ARRAY_LIST))
79 #define GEE_ARRAY_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ARRAY_LIST, GeeArrayListClass))
80
81 typedef struct _GeeArrayList GeeArrayList;
82 typedef struct _GeeArrayListClass GeeArrayListClass;
83 typedef struct _GeeHazardPointerFreeNode GeeHazardPointerFreeNode;
84
85 #define GEE_TYPE_QUEUE (gee_queue_get_type ())
86 #define GEE_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_QUEUE, GeeQueue))
87 #define GEE_IS_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_QUEUE))
88 #define GEE_QUEUE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_QUEUE, GeeQueueIface))
89
90 typedef struct _GeeQueue GeeQueue;
91 typedef struct _GeeQueueIface GeeQueueIface;
92
93 #define GEE_TYPE_COLLECTION (gee_collection_get_type ())
94 #define GEE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_COLLECTION, GeeCollection))
95 #define GEE_IS_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_COLLECTION))
96 #define GEE_COLLECTION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_COLLECTION, GeeCollectionIface))
97
98 typedef struct _GeeCollection GeeCollection;
99 typedef struct _GeeCollectionIface GeeCollectionIface;
100
101 #define GEE_TYPE_ITERABLE (gee_iterable_get_type ())
102 #define GEE_ITERABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ITERABLE, GeeIterable))
103 #define GEE_IS_ITERABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ITERABLE))
104 #define GEE_ITERABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_ITERABLE, GeeIterableIface))
105
106 typedef struct _GeeIterable GeeIterable;
107 typedef struct _GeeIterableIface GeeIterableIface;
108
109 #define GEE_TYPE_TRAVERSABLE (gee_traversable_get_type ())
110 #define GEE_TRAVERSABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_TRAVERSABLE, GeeTraversable))
111 #define GEE_IS_TRAVERSABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_TRAVERSABLE))
112 #define GEE_TRAVERSABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_TRAVERSABLE, GeeTraversableIface))
113
114 typedef struct _GeeTraversable GeeTraversable;
115 typedef struct _GeeTraversableIface GeeTraversableIface;
116 typedef gboolean (*GeeForallFunc) (gpointer g, gpointer user_data);
117 typedef enum {
118 GEE_TRAVERSABLE_STREAM_YIELD,
119 GEE_TRAVERSABLE_STREAM_CONTINUE,
120 GEE_TRAVERSABLE_STREAM_END,
121 GEE_TRAVERSABLE_STREAM_WAIT
122 } GeeTraversableStream;
123
124 #define GEE_TRAVERSABLE_TYPE_STREAM (gee_traversable_stream_get_type ())
125
126 #define GEE_TYPE_LAZY (gee_lazy_get_type ())
127 #define GEE_LAZY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_LAZY, GeeLazy))
128 #define GEE_LAZY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_LAZY, GeeLazyClass))
129 #define GEE_IS_LAZY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_LAZY))
130 #define GEE_IS_LAZY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_LAZY))
131 #define GEE_LAZY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_LAZY, GeeLazyClass))
132
133 typedef struct _GeeLazy GeeLazy;
134 typedef struct _GeeLazyClass GeeLazyClass;
135 typedef GeeTraversableStream (*GeeStreamFunc) (GeeTraversableStream state, GeeLazy* g, GeeLazy* * lazy, gpointer user_data);
136
137 #define GEE_TYPE_ITERATOR (gee_iterator_get_type ())
138 #define GEE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ITERATOR, GeeIterator))
139 #define GEE_IS_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ITERATOR))
140 #define GEE_ITERATOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_ITERATOR, GeeIteratorIface))
141
142 typedef struct _GeeIterator GeeIterator;
143 typedef struct _GeeIteratorIface GeeIteratorIface;
144 typedef gpointer (*GeeFoldFunc) (gpointer g, gpointer a, gpointer user_data);
145 typedef gpointer (*GeeMapFunc) (gpointer g, gpointer user_data);
146 typedef gboolean (*GeePredicate) (gconstpointer g, gpointer user_data);
147 typedef GeeIterator* (*GeeFlatMapFunc) (gpointer g, gpointer user_data);
148 #define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
149 typedef enum {
150 GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD,
151 GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP
152 } GeeHazardPointerReleasePolicy;
153
154 #define GEE_HAZARD_POINTER_TYPE_RELEASE_POLICY (gee_hazard_pointer_release_policy_get_type ())
155 typedef struct _GeeHazardPointerContext GeeHazardPointerContext;
156 #define _gee_hazard_pointer_context_free0(var) ((var == NULL) ? NULL : (var = (gee_hazard_pointer_context_free (var), NULL)))
157 #define _g_thread_unref0(var) ((var == NULL) ? NULL : (var = (g_thread_unref (var), NULL)))
158 typedef gboolean (*GeeEqualDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data);
159 #define _t_destroy_func0(var) (((var == NULL) || (t_destroy_func == NULL)) ? NULL : (var = (t_destroy_func (var), NULL)))
160
161 #define GEE_TYPE_LINKED_LIST (gee_linked_list_get_type ())
162 #define GEE_LINKED_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_LINKED_LIST, GeeLinkedList))
163 #define GEE_LINKED_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_LINKED_LIST, GeeLinkedListClass))
164 #define GEE_IS_LINKED_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_LINKED_LIST))
165 #define GEE_IS_LINKED_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_LINKED_LIST))
166 #define GEE_LINKED_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_LINKED_LIST, GeeLinkedListClass))
167
168 typedef struct _GeeLinkedList GeeLinkedList;
169 typedef struct _GeeLinkedListClass GeeLinkedListClass;
170 typedef struct _Block10Data Block10Data;
171 #define _g_destroy_func0(var) (((var == NULL) || (g_destroy_func == NULL)) ? NULL : (var = (g_destroy_func (var), NULL)))
172 #define _gee_hazard_pointer_free0(var) ((var == NULL) ? NULL : (var = (gee_hazard_pointer_free (var), NULL)))
173 typedef guint (*GeeHashDataFunc) (gconstpointer v, gpointer user_data);
174
175 #define GEE_TYPE_ABSTRACT_SET (gee_abstract_set_get_type ())
176 #define GEE_ABSTRACT_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_SET, GeeAbstractSet))
177 #define GEE_ABSTRACT_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_SET, GeeAbstractSetClass))
178 #define GEE_IS_ABSTRACT_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_SET))
179 #define GEE_IS_ABSTRACT_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_SET))
180 #define GEE_ABSTRACT_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_SET, GeeAbstractSetClass))
181
182 typedef struct _GeeAbstractSet GeeAbstractSet;
183 typedef struct _GeeAbstractSetClass GeeAbstractSetClass;
184
185 #define GEE_TYPE_HASH_SET (gee_hash_set_get_type ())
186 #define GEE_HASH_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_HASH_SET, GeeHashSet))
187 #define GEE_HASH_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_HASH_SET, GeeHashSetClass))
188 #define GEE_IS_HASH_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_HASH_SET))
189 #define GEE_IS_HASH_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_HASH_SET))
190 #define GEE_HASH_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_HASH_SET, GeeHashSetClass))
191
192 typedef struct _GeeHashSet GeeHashSet;
193 typedef struct _GeeHashSetClass GeeHashSetClass;
194 #define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
195 #define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
196 #define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
197 #define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
198 #define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
199
200 struct _GeeHazardPointer {
201 GeeHazardPointerNode* _node;
202 };
203
204 struct _GeeIteratorIface {
205 GTypeInterface parent_iface;
206 gboolean (*next) (GeeIterator* self);
207 gboolean (*has_next) (GeeIterator* self);
208 gpointer (*get) (GeeIterator* self);
209 void (*remove) (GeeIterator* self);
210 gboolean (*get_valid) (GeeIterator* self);
211 gboolean (*get_read_only) (GeeIterator* self);
212 };
213
214 struct _GeeTraversableIface {
215 GTypeInterface parent_iface;
216 GType (*get_g_type) (GeeTraversable* self);
217 GBoxedCopyFunc (*get_g_dup_func) (GeeTraversable* self);
218 GDestroyNotify (*get_g_destroy_func) (GeeTraversable* self);
219 gboolean (*foreach) (GeeTraversable* self, GeeForallFunc f, gpointer f_target);
220 GeeIterator* (*stream) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeStreamFunc f, gpointer f_target, GDestroyNotify f_target_destroy_notify);
221 gpointer (*fold) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldFunc f, gpointer f_target, gpointer seed);
222 GeeIterator* (*map) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeMapFunc f, gpointer f_target);
223 GeeIterator* (*scan) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldFunc f, gpointer f_target, gpointer seed);
224 GeeIterator* (*filter) (GeeTraversable* self, GeePredicate pred, gpointer pred_target, GDestroyNotify pred_target_destroy_notify);
225 GeeIterator* (*chop) (GeeTraversable* self, gint offset, gint length);
226 GType (*get_element_type) (GeeTraversable* self);
227 GeeIterator* (*flat_map) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFlatMapFunc f, gpointer f_target, GDestroyNotify f_target_destroy_notify);
228 GeeIterator** (*tee) (GeeTraversable* self, guint forks, gint* result_length1);
229 gpointer (*first_match) (GeeTraversable* self, GeePredicate pred, gpointer pred_target, GDestroyNotify pred_target_destroy_notify);
230 gboolean (*any_match) (GeeTraversable* self, GeePredicate pred, gpointer pred_target, GDestroyNotify pred_target_destroy_notify);
231 gboolean (*all_match) (GeeTraversable* self, GeePredicate pred, gpointer pred_target, GDestroyNotify pred_target_destroy_notify);
232 gpointer (*max) (GeeTraversable* self, GCompareDataFunc compare, gpointer compare_target, GDestroyNotify compare_target_destroy_notify);
233 gpointer (*min) (GeeTraversable* self, GCompareDataFunc compare, gpointer compare_target, GDestroyNotify compare_target_destroy_notify);
234 GeeIterator* (*order_by) (GeeTraversable* self, GCompareDataFunc compare, gpointer compare_target, GDestroyNotify compare_target_destroy_notify);
235 };
236
237 struct _GeeIterableIface {
238 GTypeInterface parent_iface;
239 GType (*get_g_type) (GeeIterable* self);
240 GBoxedCopyFunc (*get_g_dup_func) (GeeIterable* self);
241 GDestroyNotify (*get_g_destroy_func) (GeeIterable* self);
242 GeeIterator* (*iterator) (GeeIterable* self);
243 };
244
245 struct _GeeCollectionIface {
246 GTypeInterface parent_iface;
247 GType (*get_g_type) (GeeCollection* self);
248 GBoxedCopyFunc (*get_g_dup_func) (GeeCollection* self);
249 GDestroyNotify (*get_g_destroy_func) (GeeCollection* self);
250 gboolean (*contains) (GeeCollection* self, gconstpointer item);
251 gboolean (*add) (GeeCollection* self, gconstpointer item);
252 gboolean (*remove) (GeeCollection* self, gconstpointer item);
253 void (*clear) (GeeCollection* self);
254 gboolean (*add_all) (GeeCollection* self, GeeCollection* collection);
255 gboolean (*contains_all) (GeeCollection* self, GeeCollection* collection);
256 gboolean (*remove_all) (GeeCollection* self, GeeCollection* collection);
257 gboolean (*retain_all) (GeeCollection* self, GeeCollection* collection);
258 gpointer* (*to_array) (GeeCollection* self, gint* result_length1);
259 gint (*get_size) (GeeCollection* self);
260 gboolean (*get_is_empty) (GeeCollection* self);
261 gboolean (*get_read_only) (GeeCollection* self);
262 GeeCollection* (*get_read_only_view) (GeeCollection* self);
263 gboolean (*add_all_array) (GeeCollection* self, gpointer* array, gint array_length1);
264 gboolean (*contains_all_array) (GeeCollection* self, gpointer* array, gint array_length1);
265 gboolean (*remove_all_array) (GeeCollection* self, gpointer* array, gint array_length1);
266 gboolean (*add_all_iterator) (GeeCollection* self, GeeIterator* iter);
267 gboolean (*contains_all_iterator) (GeeCollection* self, GeeIterator* iter);
268 gboolean (*remove_all_iterator) (GeeCollection* self, GeeIterator* iter);
269 };
270
271 struct _GeeQueueIface {
272 GTypeInterface parent_iface;
273 GType (*get_g_type) (GeeQueue* self);
274 GBoxedCopyFunc (*get_g_dup_func) (GeeQueue* self);
275 GDestroyNotify (*get_g_destroy_func) (GeeQueue* self);
276 gboolean (*offer) (GeeQueue* self, gconstpointer element);
277 gpointer (*peek) (GeeQueue* self);
278 gpointer (*poll) (GeeQueue* self);
279 gint (*drain) (GeeQueue* self, GeeCollection* recipient, gint amount);
280 gint (*get_capacity) (GeeQueue* self);
281 gint (*get_remaining_capacity) (GeeQueue* self);
282 gboolean (*get_is_full) (GeeQueue* self);
283 };
284
285 struct _GeeHazardPointerContext {
286 GeeHazardPointerContext* _parent;
287 GeeArrayList* _to_free;
288 GeeHazardPointerPolicy* _policy;
289 };
290
291 struct _Block10Data {
292 int _ref_count_;
293 GeeCollection* to_free;
294 };
295
296 struct _GeeHazardPointerFreeNode {
297 void* pointer;
298 GDestroyNotify destroy_notify;
299 };
300
301 struct _GeeHazardPointerNode {
302 GeeHazardPointerNode* _next;
303 gint _active;
304 void* _hazard;
305 };
306
307 extern gint gee_hazard_pointer__default_policy;
308 extern gint gee_hazard_pointer__thread_exit_policy;
309 extern GStaticMutex gee_hazard_pointer__queue_mutex;
310 extern GeeQueue* gee_hazard_pointer__queue;
311 extern GeeArrayList* gee_hazard_pointer__global_to_free;
312 extern gint gee_hazard_pointer_release_policy;
313 extern GeeHazardPointerNode* gee_hazard_pointer__head;
314 GeeHazardPointerNode* gee_hazard_pointer__head = NULL;
315 gint gee_hazard_pointer__default_policy = (gint) GEE_HAZARD_POINTER_POLICY_TRY_FREE;
316 gint gee_hazard_pointer__thread_exit_policy = (gint) GEE_HAZARD_POINTER_POLICY_RELEASE;
317 gint gee_hazard_pointer_release_policy = 0;
318 GeeQueue* gee_hazard_pointer__queue = NULL;
319 GStaticMutex gee_hazard_pointer__queue_mutex = G_STATIC_MUTEX_INIT;
320 GeeArrayList* gee_hazard_pointer__global_to_free = NULL;
321 static guint gee_hazard_pointer_context_THRESHOLD;
322 extern GStaticPrivate gee_hazard_pointer_context__current_context;
323 GStaticPrivate gee_hazard_pointer_context__current_context = G_STATIC_PRIVATE_INIT;
324 extern GStaticPrivate gee_hazard_pointer_context__root_context;
325 GStaticPrivate gee_hazard_pointer_context__root_context = G_STATIC_PRIVATE_INIT;
326 static guint gee_hazard_pointer_context_THRESHOLD = (guint) 10;
327
328 void gee_hazard_pointer_free (GeeHazardPointer * self);
329 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeHazardPointer, gee_hazard_pointer_free)
330 G_GNUC_INTERNAL void gee_hazard_pointer_node_free (GeeHazardPointerNode * self);
331 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeHazardPointerNode, gee_hazard_pointer_node_free)
332 static void gee_hazard_pointer_instance_init (GeeHazardPointer * self);
333 G_GNUC_INTERNAL void gee_hazard_pointer_node_release (GeeHazardPointerNode* self);
334 GType gee_hazard_pointer_policy_get_type (void) G_GNUC_CONST;
335 gboolean gee_hazard_pointer_policy_is_concrete (GeeHazardPointerPolicy self);
336 gboolean gee_hazard_pointer_policy_is_blocking (GeeHazardPointerPolicy self);
337 gboolean gee_hazard_pointer_policy_is_safe (GeeHazardPointerPolicy self);
338 GeeHazardPointerPolicy gee_hazard_pointer_policy_to_concrete (GeeHazardPointerPolicy self);
339 GType gee_abstract_collection_get_type (void) G_GNUC_CONST;
340 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeAbstractCollection, g_object_unref)
341 GType gee_abstract_list_get_type (void) G_GNUC_CONST;
342 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeAbstractList, g_object_unref)
343 GType gee_abstract_bidir_list_get_type (void) G_GNUC_CONST;
344 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeAbstractBidirList, g_object_unref)
345 GType gee_array_list_get_type (void) G_GNUC_CONST;
346 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeArrayList, g_object_unref)
347 G_GNUC_INTERNAL void gee_hazard_pointer_free_node_free (GeeHazardPointerFreeNode * self);
348 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeHazardPointerFreeNode, gee_hazard_pointer_free_node_free)
349 G_GNUC_INTERNAL gboolean gee_hazard_pointer_policy_perform (GeeHazardPointerPolicy self,
350 GeeArrayList* * to_free);
351 G_GNUC_INTERNAL gboolean gee_hazard_pointer_try_free (GeeArrayList* to_free);
352 G_GNUC_INTERNAL void gee_hazard_pointer_release_policy_ensure_start (void);
353 GType gee_traversable_stream_get_type (void) G_GNUC_CONST;
354 gpointer gee_lazy_ref (gpointer instance);
355 void gee_lazy_unref (gpointer instance);
356 GParamSpec* gee_param_spec_lazy (const gchar* name,
357 const gchar* nick,
358 const gchar* blurb,
359 GType object_type,
360 GParamFlags flags);
361 void gee_value_set_lazy (GValue* value,
362 gpointer v_object);
363 void gee_value_take_lazy (GValue* value,
364 gpointer v_object);
365 gpointer gee_value_get_lazy (const GValue* value);
366 GType gee_lazy_get_type (void) G_GNUC_CONST;
367 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeLazy, gee_lazy_unref)
368 GType gee_iterator_get_type (void) G_GNUC_CONST;
369 GType gee_traversable_get_type (void) G_GNUC_CONST;
370 GType gee_iterable_get_type (void) G_GNUC_CONST;
371 GType gee_collection_get_type (void) G_GNUC_CONST;
372 GType gee_queue_get_type (void) G_GNUC_CONST;
373 gboolean gee_queue_offer (GeeQueue* self,
374 gconstpointer element);
375 GType gee_hazard_pointer_release_policy_get_type (void) G_GNUC_CONST;
376 static void gee_hazard_pointer_release_policy_start (GeeHazardPointerReleasePolicy _self_);
377 static gboolean ___lambda54_ (void);
378 void gee_hazard_pointer_context_free (GeeHazardPointerContext * self);
379 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeHazardPointerContext, gee_hazard_pointer_context_free)
380 GeeHazardPointerContext* gee_hazard_pointer_context_new (GeeHazardPointerPolicy* policy);
381 static inline void gee_hazard_pointer_release_policy_pull_from_queue (GeeCollection* to_free,
382 gboolean do_lock);
383 gboolean gee_collection_get_is_empty (GeeCollection* self);
384 void gee_hazard_pointer_context_try_free (GeeHazardPointerContext* self);
385 static gpointer ____lambda54__gthread_func (gpointer self);
386 GeeArrayList* gee_array_list_new (GType g_type,
387 GBoxedCopyFunc g_dup_func,
388 GDestroyNotify g_destroy_func,
389 GeeEqualDataFunc equal_func,
390 gpointer equal_func_target,
391 GDestroyNotify equal_func_target_destroy_notify);
392 GeeArrayList* gee_array_list_construct (GType object_type,
393 GType g_type,
394 GBoxedCopyFunc g_dup_func,
395 GDestroyNotify g_destroy_func,
396 GeeEqualDataFunc equal_func,
397 gpointer equal_func_target,
398 GDestroyNotify equal_func_target_destroy_notify);
399 static gboolean ___lambda56_ (void);
400 static void gee_hazard_pointer_release_policy_swap (GType t_type,
401 GBoxedCopyFunc t_dup_func,
402 GDestroyNotify t_destroy_func,
403 gpointer* a,
404 gpointer* b);
405 static gboolean ____lambda56__gsource_func (gpointer self);
406 GeeLinkedList* gee_linked_list_new (GType g_type,
407 GBoxedCopyFunc g_dup_func,
408 GDestroyNotify g_destroy_func,
409 GeeEqualDataFunc equal_func,
410 gpointer equal_func_target,
411 GDestroyNotify equal_func_target_destroy_notify);
412 GeeLinkedList* gee_linked_list_construct (GType object_type,
413 GType g_type,
414 GBoxedCopyFunc g_dup_func,
415 GDestroyNotify g_destroy_func,
416 GeeEqualDataFunc equal_func,
417 gpointer equal_func_target,
418 GDestroyNotify equal_func_target_destroy_notify);
419 GType gee_linked_list_get_type (void) G_GNUC_CONST;
420 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeLinkedList, g_object_unref)
421 static Block10Data* block10_data_ref (Block10Data* _data10_);
422 static void block10_data_unref (void * _userdata_);
423 gint gee_queue_drain (GeeQueue* self,
424 GeeCollection* recipient,
425 gint amount);
426 gboolean gee_traversable_foreach (GeeTraversable* self,
427 GeeForallFunc f,
428 gpointer f_target);
429 static gboolean ___lambda55_ (Block10Data* _data10_,
430 GeeArrayList* x);
431 gboolean gee_collection_add_all (GeeCollection* self,
432 GeeCollection* collection);
433 static gboolean ____lambda55__gee_forall_func (gpointer g,
434 gpointer self);
435 GeeHazardPointer* gee_hazard_pointer_new (gconstpointer* ptr);
436 G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_acquire (void);
437 G_GNUC_INTERNAL void gee_hazard_pointer_node_set (GeeHazardPointerNode* self,
438 void* ptr);
439 G_GNUC_INTERNAL GeeHazardPointer* gee_hazard_pointer_new_from_node (GeeHazardPointerNode* node);
440 GeeHazardPointer* gee_hazard_pointer_get_hazard_pointer (GType g_type,
441 GBoxedCopyFunc g_dup_func,
442 GDestroyNotify g_destroy_func,
443 gconstpointer** aptr,
444 gsize mask,
445 gsize* mask_out);
446 gpointer gee_hazard_pointer_get_pointer (GType g_type,
447 GBoxedCopyFunc g_dup_func,
448 GDestroyNotify g_destroy_func,
449 gconstpointer** aptr,
450 gsize mask,
451 gsize* mask_out);
452 GeeHazardPointer* gee_hazard_pointer_exchange_hazard_pointer (GType g_type,
453 GBoxedCopyFunc g_dup_func,
454 GDestroyNotify g_destroy_func,
455 gconstpointer** aptr,
456 gpointer new_ptr,
457 gsize mask,
458 gsize new_mask,
459 gsize* old_mask);
460 void gee_hazard_pointer_set_pointer (GType g_type,
461 GBoxedCopyFunc g_dup_func,
462 GDestroyNotify g_destroy_func,
463 gconstpointer** aptr,
464 gpointer new_ptr,
465 gsize mask,
466 gsize new_mask);
467 void gee_hazard_pointer_release (GeeHazardPointer* self,
468 GDestroyNotify notify);
469 gpointer gee_hazard_pointer_exchange_pointer (GType g_type,
470 GBoxedCopyFunc g_dup_func,
471 GDestroyNotify g_destroy_func,
472 gconstpointer** aptr,
473 gpointer new_ptr,
474 gsize mask,
475 gsize new_mask,
476 gsize* old_mask);
477 gconstpointer gee_hazard_pointer_get (GeeHazardPointer* self,
478 gboolean other_thread);
479 gboolean gee_hazard_pointer_compare_and_exchange_pointer (GType g_type,
480 GBoxedCopyFunc g_dup_func,
481 GDestroyNotify g_destroy_func,
482 gconstpointer** aptr,
483 gconstpointer old_ptr,
484 gpointer _new_ptr,
485 gsize mask,
486 gsize old_mask,
487 gsize new_mask);
488 G_GNUC_INTERNAL GeeHazardPointerContext* gee_hazard_pointer_context_get_current_context (void);
489 G_GNUC_INTERNAL void gee_hazard_pointer_context_release_ptr (GeeHazardPointerContext* self,
490 void* ptr,
491 GDestroyNotify notify);
492 G_GNUC_INTERNAL void* gee_hazard_pointer_node_get (GeeHazardPointerNode* self,
493 gboolean safe);
494 void gee_hazard_pointer_set_default_policy (GeeHazardPointerPolicy policy);
495 void gee_hazard_pointer_set_thread_exit_policy (GeeHazardPointerPolicy policy);
496 gboolean gee_hazard_pointer_set_release_policy (GeeHazardPointerReleasePolicy policy);
497 G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_get_head (void);
498 G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_get_next (GeeHazardPointerNode* self);
499 G_GNUC_INTERNAL gboolean gee_hazard_pointer_node_activate (GeeHazardPointerNode* self);
500 G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_new (void);
501 G_GNUC_INTERNAL void gee_hazard_pointer_node_set_next (GeeHazardPointerNode* self,
502 GeeHazardPointerNode* next);
503 GeeHashSet* gee_hash_set_new (GType g_type,
504 GBoxedCopyFunc g_dup_func,
505 GDestroyNotify g_destroy_func,
506 GeeHashDataFunc hash_func,
507 gpointer hash_func_target,
508 GDestroyNotify hash_func_target_destroy_notify,
509 GeeEqualDataFunc equal_func,
510 gpointer equal_func_target,
511 GDestroyNotify equal_func_target_destroy_notify);
512 GeeHashSet* gee_hash_set_construct (GType object_type,
513 GType g_type,
514 GBoxedCopyFunc g_dup_func,
515 GDestroyNotify g_destroy_func,
516 GeeHashDataFunc hash_func,
517 gpointer hash_func_target,
518 GDestroyNotify hash_func_target_destroy_notify,
519 GeeEqualDataFunc equal_func,
520 gpointer equal_func_target,
521 GDestroyNotify equal_func_target_destroy_notify);
522 GType gee_abstract_set_get_type (void) G_GNUC_CONST;
523 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeAbstractSet, g_object_unref)
524 GType gee_hash_set_get_type (void) G_GNUC_CONST;
525 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeeHashSet, g_object_unref)
526 gboolean gee_collection_add (GeeCollection* self,
527 gconstpointer item);
528 gint gee_abstract_collection_get_size (GeeAbstractCollection* self);
529 gpointer gee_abstract_list_get (GeeAbstractList* self,
530 gint index);
531 gboolean gee_collection_contains (GeeCollection* self,
532 gconstpointer item);
533 gpointer gee_abstract_list_remove_at (GeeAbstractList* self,
534 gint index);
535 void gee_abstract_list_set (GeeAbstractList* self,
536 gint index,
537 gconstpointer item);
538 static void gee_hazard_pointer_context_instance_init (GeeHazardPointerContext * self);
539 gboolean gee_array_list_add_all (GeeArrayList* self,
540 GeeCollection* collection);
541 static GeeHazardPointerPolicy* _gee_hazard_pointer_policy_dup (GeeHazardPointerPolicy* self);
542 void gee_hazard_pointer_context_free_all (GeeHazardPointerContext* self);
543 void gee_hazard_pointer_context_try_release (GeeHazardPointerContext* self);
544 void gee_hazard_pointer_context_release (GeeHazardPointerContext* self);
545 G_GNUC_INTERNAL GeeHazardPointerFreeNode* gee_hazard_pointer_free_node_new (void);
546 gboolean gee_abstract_collection_add (GeeAbstractCollection* self,
547 gconstpointer item);
548 static void gee_hazard_pointer_free_node_instance_init (GeeHazardPointerFreeNode * self);
549 static void gee_hazard_pointer_node_instance_init (GeeHazardPointerNode * self);
550 G_GNUC_INTERNAL gboolean gee_hazard_pointer_node_is_active (GeeHazardPointerNode* self);
551
552 /**
553 * Policy determines what happens on exit from Context.
554 */
555 /**
556 * Checks if the policy is concrete or if it depends on global variables.
557 *
558 * @return ``true`` if this policy does not depend on global variables
559 */
560 gboolean
gee_hazard_pointer_policy_is_concrete(GeeHazardPointerPolicy self)561 gee_hazard_pointer_policy_is_concrete (GeeHazardPointerPolicy self)
562 {
563 gboolean result = FALSE;
564 switch (self) {
565 case GEE_HAZARD_POINTER_POLICY_DEFAULT:
566 case GEE_HAZARD_POINTER_POLICY_THREAD_EXIT:
567 {
568 result = FALSE;
569 return result;
570 }
571 case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
572 case GEE_HAZARD_POINTER_POLICY_FREE:
573 case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
574 case GEE_HAZARD_POINTER_POLICY_RELEASE:
575 {
576 result = TRUE;
577 return result;
578 }
579 default:
580 {
581 g_assert_not_reached ();
582 }
583 }
584 }
585
586 /**
587 * Checks if policy blocks or is lock-free.
588 * Please note that it works on a concrete policy only.
589 *
590 * @return ``true`` if the policy may block the thread.
591 */
592 gboolean
gee_hazard_pointer_policy_is_blocking(GeeHazardPointerPolicy self)593 gee_hazard_pointer_policy_is_blocking (GeeHazardPointerPolicy self)
594 {
595 gboolean result = FALSE;
596 _vala_return_val_if_fail (gee_hazard_pointer_policy_is_concrete (self), "this.is_concrete ()", FALSE);
597 switch (self) {
598 case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
599 case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
600 {
601 result = FALSE;
602 return result;
603 }
604 case GEE_HAZARD_POINTER_POLICY_FREE:
605 case GEE_HAZARD_POINTER_POLICY_RELEASE:
606 {
607 result = TRUE;
608 return result;
609 }
610 default:
611 {
612 g_assert_not_reached ();
613 }
614 }
615 }
616
617 /**
618 * Checks if policy guarantees freeing all elements.
619 * Please note that it works on a concrete policy only.
620 *
621 * @return ``true`` if the policy guarantees freeing all elements.
622 */
623 gboolean
gee_hazard_pointer_policy_is_safe(GeeHazardPointerPolicy self)624 gee_hazard_pointer_policy_is_safe (GeeHazardPointerPolicy self)
625 {
626 gboolean result = FALSE;
627 _vala_return_val_if_fail (gee_hazard_pointer_policy_is_concrete (self), "this.is_concrete ()", FALSE);
628 switch (self) {
629 case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
630 case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
631 {
632 result = FALSE;
633 return result;
634 }
635 case GEE_HAZARD_POINTER_POLICY_FREE:
636 case GEE_HAZARD_POINTER_POLICY_RELEASE:
637 {
638 result = TRUE;
639 return result;
640 }
641 default:
642 {
643 g_assert_not_reached ();
644 }
645 }
646 }
647
648 /**
649 * Finds concrete policy which corresponds to given policy.
650 *
651 * @return Policy that corresponds to given policy at given time in given thread.
652 */
653 GeeHazardPointerPolicy
gee_hazard_pointer_policy_to_concrete(GeeHazardPointerPolicy self)654 gee_hazard_pointer_policy_to_concrete (GeeHazardPointerPolicy self)
655 {
656 GeeHazardPointerPolicy _tmp5_;
657 GeeHazardPointerPolicy result = 0;
658 switch (self) {
659 case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
660 case GEE_HAZARD_POINTER_POLICY_FREE:
661 case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
662 case GEE_HAZARD_POINTER_POLICY_RELEASE:
663 {
664 GeeHazardPointerPolicy _tmp0_;
665 result = self;
666 _tmp0_ = result;
667 _vala_warn_if_fail (gee_hazard_pointer_policy_is_concrete (_tmp0_), "result.is_concrete ()");
668 return result;
669 }
670 case GEE_HAZARD_POINTER_POLICY_DEFAULT:
671 {
672 gint _tmp1_;
673 GeeHazardPointerPolicy _tmp2_;
674 _tmp1_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__default_policy));
675 result = (GeeHazardPointerPolicy) _tmp1_;
676 _tmp2_ = result;
677 _vala_warn_if_fail (gee_hazard_pointer_policy_is_concrete (_tmp2_), "result.is_concrete ()");
678 return result;
679 }
680 case GEE_HAZARD_POINTER_POLICY_THREAD_EXIT:
681 {
682 gint _tmp3_;
683 GeeHazardPointerPolicy _tmp4_;
684 _tmp3_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy));
685 result = (GeeHazardPointerPolicy) _tmp3_;
686 _tmp4_ = result;
687 _vala_warn_if_fail (gee_hazard_pointer_policy_is_concrete (_tmp4_), "result.is_concrete ()");
688 return result;
689 }
690 default:
691 {
692 g_assert_not_reached ();
693 }
694 }
695 _tmp5_ = result;
696 _vala_warn_if_fail (gee_hazard_pointer_policy_is_concrete (_tmp5_), "result.is_concrete ()");
697 }
698
699 /**
700 * Runs the policy.
701 * @param to_free List containing elements to free.
702 * @return Non-empty list of not freed elements or ``null`` if all elements have been disposed.
703 */
704 G_GNUC_INTERNAL gboolean
gee_hazard_pointer_policy_perform(GeeHazardPointerPolicy self,GeeArrayList ** to_free)705 gee_hazard_pointer_policy_perform (GeeHazardPointerPolicy self,
706 GeeArrayList* * to_free)
707 {
708 gboolean result = FALSE;
709 g_return_val_if_fail (*to_free != NULL, FALSE);
710 switch (gee_hazard_pointer_policy_to_concrete (self)) {
711 case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
712 {
713 result = gee_hazard_pointer_try_free (*to_free);
714 return result;
715 }
716 case GEE_HAZARD_POINTER_POLICY_FREE:
717 {
718 while (TRUE) {
719 if (!gee_hazard_pointer_try_free (*to_free)) {
720 break;
721 }
722 g_thread_yield ();
723 }
724 break;
725 }
726 case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
727 {
728 gee_hazard_pointer_release_policy_ensure_start ();
729 if (g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex)) {
730 GeeQueue* _tmp0_;
731 GeeArrayList* _tmp1_;
732 GeeArrayList* _tmp2_;
733 _tmp0_ = gee_hazard_pointer__queue;
734 _tmp1_ = *to_free;
735 *to_free = NULL;
736 _tmp2_ = _tmp1_;
737 gee_queue_offer (_tmp0_, _tmp2_);
738 _g_object_unref0 (_tmp2_);
739 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
740 result = TRUE;
741 return result;
742 } else {
743 result = FALSE;
744 return result;
745 }
746 }
747 case GEE_HAZARD_POINTER_POLICY_RELEASE:
748 {
749 GeeQueue* _tmp3_;
750 GeeArrayList* _tmp4_;
751 GeeArrayList* _tmp5_;
752 gee_hazard_pointer_release_policy_ensure_start ();
753 g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
754 _tmp3_ = gee_hazard_pointer__queue;
755 _tmp4_ = *to_free;
756 *to_free = NULL;
757 _tmp5_ = _tmp4_;
758 gee_queue_offer (_tmp3_, _tmp5_);
759 _g_object_unref0 (_tmp5_);
760 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
761 result = TRUE;
762 return result;
763 }
764 default:
765 {
766 g_assert_not_reached ();
767 }
768 }
769 result = FALSE;
770 return result;
771 }
772
773 GType
gee_hazard_pointer_policy_get_type(void)774 gee_hazard_pointer_policy_get_type (void)
775 {
776 static volatile gsize gee_hazard_pointer_policy_type_id__volatile = 0;
777 if (g_once_init_enter (&gee_hazard_pointer_policy_type_id__volatile)) {
778 static const GEnumValue values[] = {{GEE_HAZARD_POINTER_POLICY_DEFAULT, "GEE_HAZARD_POINTER_POLICY_DEFAULT", "default"}, {GEE_HAZARD_POINTER_POLICY_THREAD_EXIT, "GEE_HAZARD_POINTER_POLICY_THREAD_EXIT", "thread-exit"}, {GEE_HAZARD_POINTER_POLICY_TRY_FREE, "GEE_HAZARD_POINTER_POLICY_TRY_FREE", "try-free"}, {GEE_HAZARD_POINTER_POLICY_FREE, "GEE_HAZARD_POINTER_POLICY_FREE", "free"}, {GEE_HAZARD_POINTER_POLICY_TRY_RELEASE, "GEE_HAZARD_POINTER_POLICY_TRY_RELEASE", "try-release"}, {GEE_HAZARD_POINTER_POLICY_RELEASE, "GEE_HAZARD_POINTER_POLICY_RELEASE", "release"}, {0, NULL, NULL}};
779 GType gee_hazard_pointer_policy_type_id;
780 gee_hazard_pointer_policy_type_id = g_enum_register_static ("GeeHazardPointerPolicy", values);
781 g_once_init_leave (&gee_hazard_pointer_policy_type_id__volatile, gee_hazard_pointer_policy_type_id);
782 }
783 return gee_hazard_pointer_policy_type_id__volatile;
784 }
785
786 /**
787 * Release policy determines what happens with object freed by Policy.TRY_RELEASE
788 * and Policy.RELEASE.
789 */
790 static gboolean
___lambda54_(void)791 ___lambda54_ (void)
792 {
793 GeeHazardPointerContext* ctx = NULL;
794 GeeHazardPointerPolicy _tmp0_;
795 GeeHazardPointerContext* _tmp1_;
796 _tmp0_ = GEE_HAZARD_POINTER_POLICY_TRY_FREE;
797 _tmp1_ = gee_hazard_pointer_context_new (&_tmp0_);
798 ctx = _tmp1_;
799 while (TRUE) {
800 GeeHazardPointerContext* _tmp2_;
801 GeeArrayList* _tmp3_;
802 GeeHazardPointerContext* _tmp4_;
803 GeeArrayList* _tmp5_;
804 gboolean _tmp6_;
805 gboolean _tmp7_;
806 GeeHazardPointerContext* _tmp8_;
807 GeeHazardPointerContext* _tmp9_;
808 GeeArrayList* _tmp10_;
809 gboolean _tmp11_;
810 gboolean _tmp12_;
811 g_thread_yield ();
812 _tmp2_ = ctx;
813 _tmp3_ = _tmp2_->_to_free;
814 _tmp4_ = ctx;
815 _tmp5_ = _tmp4_->_to_free;
816 _tmp6_ = gee_collection_get_is_empty ((GeeCollection*) _tmp5_);
817 _tmp7_ = _tmp6_;
818 gee_hazard_pointer_release_policy_pull_from_queue ((GeeCollection*) _tmp3_, _tmp7_);
819 _tmp8_ = ctx;
820 gee_hazard_pointer_context_try_free (_tmp8_);
821 _tmp9_ = ctx;
822 _tmp10_ = _tmp9_->_to_free;
823 _tmp11_ = gee_collection_get_is_empty ((GeeCollection*) _tmp10_);
824 _tmp12_ = _tmp11_;
825 if (_tmp12_) {
826 g_usleep ((gulong) 100000);
827 }
828 }
829 _gee_hazard_pointer_context_free0 (ctx);
830 }
831
832 static gpointer
____lambda54__gthread_func(gpointer self)833 ____lambda54__gthread_func (gpointer self)
834 {
835 gpointer result;
836 result = (gpointer) ((gintptr) ___lambda54_ ());
837 return result;
838 }
839
840 static gboolean
___lambda56_(void)841 ___lambda56_ (void)
842 {
843 GeeHazardPointerContext* ctx = NULL;
844 GeeHazardPointerPolicy _tmp0_;
845 GeeHazardPointerContext* _tmp1_;
846 GeeArrayList* _tmp2_;
847 gboolean result = FALSE;
848 _tmp0_ = GEE_HAZARD_POINTER_POLICY_TRY_FREE;
849 _tmp1_ = gee_hazard_pointer_context_new (&_tmp0_);
850 ctx = _tmp1_;
851 gee_hazard_pointer_release_policy_swap (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, &gee_hazard_pointer__global_to_free, &ctx->_to_free);
852 _tmp2_ = ctx->_to_free;
853 gee_hazard_pointer_release_policy_pull_from_queue ((GeeCollection*) _tmp2_, FALSE);
854 gee_hazard_pointer_context_try_free (ctx);
855 gee_hazard_pointer_release_policy_swap (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, &gee_hazard_pointer__global_to_free, &ctx->_to_free);
856 result = TRUE;
857 _gee_hazard_pointer_context_free0 (ctx);
858 return result;
859 }
860
861 static gboolean
____lambda56__gsource_func(gpointer self)862 ____lambda56__gsource_func (gpointer self)
863 {
864 gboolean result;
865 result = ___lambda56_ ();
866 return result;
867 }
868
869 static void
gee_hazard_pointer_release_policy_start(GeeHazardPointerReleasePolicy _self_)870 gee_hazard_pointer_release_policy_start (GeeHazardPointerReleasePolicy _self_)
871 {
872 switch (_self_) {
873 case GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD:
874 {
875 GThread* _tmp0_;
876 GThread* _tmp1_;
877 _tmp0_ = g_thread_new ("<<libgee hazard pointer>>", ____lambda54__gthread_func, NULL);
878 _tmp1_ = _tmp0_;
879 _g_thread_unref0 (_tmp1_);
880 break;
881 }
882 case GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP:
883 {
884 GeeArrayList* _tmp2_;
885 _tmp2_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
886 _g_object_unref0 (gee_hazard_pointer__global_to_free);
887 gee_hazard_pointer__global_to_free = _tmp2_;
888 g_idle_add_full (G_PRIORITY_LOW, ____lambda56__gsource_func, NULL, NULL);
889 break;
890 }
891 default:
892 {
893 g_assert_not_reached ();
894 }
895 }
896 }
897
898 static void
gee_hazard_pointer_release_policy_swap(GType t_type,GBoxedCopyFunc t_dup_func,GDestroyNotify t_destroy_func,gpointer * a,gpointer * b)899 gee_hazard_pointer_release_policy_swap (GType t_type,
900 GBoxedCopyFunc t_dup_func,
901 GDestroyNotify t_destroy_func,
902 gpointer* a,
903 gpointer* b)
904 {
905 gpointer tmp = NULL;
906 gpointer _tmp0_;
907 gpointer _tmp1_;
908 gpointer _tmp2_;
909 _tmp0_ = *a;
910 *a = NULL;
911 tmp = _tmp0_;
912 _tmp1_ = *b;
913 *b = NULL;
914 _t_destroy_func0 (*a);
915 *a = _tmp1_;
916 _tmp2_ = tmp;
917 tmp = NULL;
918 _t_destroy_func0 (*b);
919 *b = _tmp2_;
920 _t_destroy_func0 (tmp);
921 }
922
923 /**
924 * Ensures that helper methods are started.
925 */
926 G_GNUC_INTERNAL inline void
gee_hazard_pointer_release_policy_ensure_start(void)927 gee_hazard_pointer_release_policy_ensure_start (void)
928 {
929 gint policy = 0;
930 gint _tmp0_;
931 _tmp0_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
932 policy = _tmp0_;
933 if ((policy & (1 << ((sizeof (gint) * 8) - 1))) != 0) {
934 return;
935 }
936 if (g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex)) {
937 gint _tmp1_;
938 _tmp1_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
939 policy = _tmp1_;
940 if ((policy & (1 << ((sizeof (gint) * 8) - 1))) == 0) {
941 GeeLinkedList* _tmp2_;
942 gint _tmp3_;
943 _tmp2_ = gee_linked_list_new (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
944 _g_object_unref0 (gee_hazard_pointer__queue);
945 gee_hazard_pointer__queue = (GeeQueue*) _tmp2_;
946 _tmp3_ = g_atomic_int_add ((volatile gint *) (&gee_hazard_pointer_release_policy), (gint) (1 << ((sizeof (gint) * 8) - 1)));
947 policy = _tmp3_;
948 gee_hazard_pointer_release_policy_start ((GeeHazardPointerReleasePolicy) policy);
949 }
950 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
951 }
952 }
953
954 static gpointer
_g_object_ref0(gpointer self)955 _g_object_ref0 (gpointer self)
956 {
957 return self ? g_object_ref (self) : NULL;
958 }
959
960 static Block10Data*
block10_data_ref(Block10Data * _data10_)961 block10_data_ref (Block10Data* _data10_)
962 {
963 g_atomic_int_inc (&_data10_->_ref_count_);
964 return _data10_;
965 }
966
967 static void
block10_data_unref(void * _userdata_)968 block10_data_unref (void * _userdata_)
969 {
970 Block10Data* _data10_;
971 _data10_ = (Block10Data*) _userdata_;
972 if (g_atomic_int_dec_and_test (&_data10_->_ref_count_)) {
973 _g_object_unref0 (_data10_->to_free);
974 g_slice_free (Block10Data, _data10_);
975 }
976 }
977
978 static gboolean
___lambda55_(Block10Data * _data10_,GeeArrayList * x)979 ___lambda55_ (Block10Data* _data10_,
980 GeeArrayList* x)
981 {
982 gboolean result = FALSE;
983 g_return_val_if_fail (x != NULL, FALSE);
984 gee_collection_add_all (_data10_->to_free, (GeeCollection*) x);
985 result = TRUE;
986 _g_object_unref0 (x);
987 return result;
988 }
989
990 static gboolean
____lambda55__gee_forall_func(gpointer g,gpointer self)991 ____lambda55__gee_forall_func (gpointer g,
992 gpointer self)
993 {
994 gboolean result;
995 result = ___lambda55_ (self, (GeeArrayList*) g);
996 return result;
997 }
998
999 static inline void
gee_hazard_pointer_release_policy_pull_from_queue(GeeCollection * to_free,gboolean do_lock)1000 gee_hazard_pointer_release_policy_pull_from_queue (GeeCollection* to_free,
1001 gboolean do_lock)
1002 {
1003 Block10Data* _data10_;
1004 GeeCollection* _tmp0_;
1005 gboolean locked = FALSE;
1006 g_return_if_fail (to_free != NULL);
1007 _data10_ = g_slice_new0 (Block10Data);
1008 _data10_->_ref_count_ = 1;
1009 _tmp0_ = _g_object_ref0 (to_free);
1010 _g_object_unref0 (_data10_->to_free);
1011 _data10_->to_free = _tmp0_;
1012 locked = do_lock;
1013 if (do_lock) {
1014 g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
1015 } else {
1016 locked = g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex);
1017 }
1018 if (locked) {
1019 GeeCollection* temp = NULL;
1020 GeeArrayList* _tmp1_;
1021 GeeQueue* _tmp2_;
1022 GeeCollection* _tmp3_;
1023 GeeCollection* _tmp4_;
1024 _tmp1_ = gee_array_list_new (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
1025 temp = (GeeCollection*) _tmp1_;
1026 _tmp2_ = gee_hazard_pointer__queue;
1027 _tmp3_ = temp;
1028 gee_queue_drain (_tmp2_, _tmp3_, -1);
1029 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
1030 _tmp4_ = temp;
1031 gee_traversable_foreach ((GeeTraversable*) _tmp4_, ____lambda55__gee_forall_func, _data10_);
1032 _g_object_unref0 (temp);
1033 }
1034 block10_data_unref (_data10_);
1035 _data10_ = NULL;
1036 }
1037
1038 GType
gee_hazard_pointer_release_policy_get_type(void)1039 gee_hazard_pointer_release_policy_get_type (void)
1040 {
1041 static volatile gsize gee_hazard_pointer_release_policy_type_id__volatile = 0;
1042 if (g_once_init_enter (&gee_hazard_pointer_release_policy_type_id__volatile)) {
1043 static const GEnumValue values[] = {{GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD, "GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD", "helper-thread"}, {GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP, "GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP", "main-loop"}, {0, NULL, NULL}};
1044 GType gee_hazard_pointer_release_policy_type_id;
1045 gee_hazard_pointer_release_policy_type_id = g_enum_register_static ("GeeHazardPointerReleasePolicy", values);
1046 g_once_init_leave (&gee_hazard_pointer_release_policy_type_id__volatile, gee_hazard_pointer_release_policy_type_id);
1047 }
1048 return gee_hazard_pointer_release_policy_type_id__volatile;
1049 }
1050
1051 /**
1052 * Creates a hazard pointer for a pointer.
1053 *
1054 * @param ptr Protected pointer
1055 */
1056 GeeHazardPointer*
gee_hazard_pointer_new(gconstpointer * ptr)1057 gee_hazard_pointer_new (gconstpointer* ptr)
1058 {
1059 GeeHazardPointer* self;
1060 GeeHazardPointerNode* _tmp0_;
1061 GeeHazardPointerNode* _tmp1_;
1062 self = g_slice_new0 (GeeHazardPointer);
1063 gee_hazard_pointer_instance_init (self);
1064 _tmp0_ = gee_hazard_pointer_acquire ();
1065 self->_node = _tmp0_;
1066 _tmp1_ = self->_node;
1067 gee_hazard_pointer_node_set (_tmp1_, (void*) ptr);
1068 return self;
1069 }
1070
1071 /**
1072 * Create a hazard pointer from Node.
1073 */
1074 G_GNUC_INTERNAL GeeHazardPointer*
gee_hazard_pointer_new_from_node(GeeHazardPointerNode * node)1075 gee_hazard_pointer_new_from_node (GeeHazardPointerNode* node)
1076 {
1077 GeeHazardPointer* self;
1078 g_return_val_if_fail (node != NULL, NULL);
1079 self = g_slice_new0 (GeeHazardPointer);
1080 gee_hazard_pointer_instance_init (self);
1081 self->_node = node;
1082 return self;
1083 }
1084
1085 /**
1086 * Gets hazard pointer from atomic pointer safely.
1087 *
1088 * @param aptr Atomic pointer.
1089 * @param mask Mask of bits.
1090 * @param mask_out Result of mask.
1091 * @return Hazard pointer containing the element.
1092 */
1093 GeeHazardPointer*
gee_hazard_pointer_get_hazard_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gsize mask,gsize * mask_out)1094 gee_hazard_pointer_get_hazard_pointer (GType g_type,
1095 GBoxedCopyFunc g_dup_func,
1096 GDestroyNotify g_destroy_func,
1097 gconstpointer** aptr,
1098 gsize mask,
1099 gsize* mask_out)
1100 {
1101 gsize _vala_mask_out = 0UL;
1102 GeeHazardPointerNode* node = NULL;
1103 GeeHazardPointerNode* _tmp0_;
1104 void* rptr = NULL;
1105 void* ptr = NULL;
1106 void* _tmp9_;
1107 GeeHazardPointer* result = NULL;
1108 _tmp0_ = gee_hazard_pointer_acquire ();
1109 node = _tmp0_;
1110 rptr = NULL;
1111 ptr = NULL;
1112 _vala_mask_out = (gsize) 0;
1113 {
1114 gboolean _tmp1_ = FALSE;
1115 _tmp1_ = TRUE;
1116 while (TRUE) {
1117 void* _tmp4_;
1118 void* _tmp5_;
1119 void* _tmp6_;
1120 GeeHazardPointerNode* _tmp7_;
1121 void* _tmp8_;
1122 if (!_tmp1_) {
1123 void* _tmp2_;
1124 void* _tmp3_;
1125 _tmp2_ = rptr;
1126 _tmp3_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) aptr));
1127 if (!(_tmp2_ != _tmp3_)) {
1128 break;
1129 }
1130 }
1131 _tmp1_ = FALSE;
1132 _tmp4_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) aptr));
1133 rptr = _tmp4_;
1134 _tmp5_ = rptr;
1135 ptr = (void*) (((gsize) _tmp5_) & (~mask));
1136 _tmp6_ = rptr;
1137 _vala_mask_out = ((gsize) _tmp6_) & mask;
1138 _tmp7_ = node;
1139 _tmp8_ = ptr;
1140 gee_hazard_pointer_node_set (_tmp7_, _tmp8_);
1141 }
1142 }
1143 _tmp9_ = ptr;
1144 if (_tmp9_ != NULL) {
1145 GeeHazardPointerNode* _tmp10_;
1146 GeeHazardPointer* _tmp11_;
1147 _tmp10_ = node;
1148 _tmp11_ = gee_hazard_pointer_new_from_node (_tmp10_);
1149 result = _tmp11_;
1150 if (mask_out) {
1151 *mask_out = _vala_mask_out;
1152 }
1153 return result;
1154 } else {
1155 GeeHazardPointerNode* _tmp12_;
1156 _tmp12_ = node;
1157 gee_hazard_pointer_node_release (_tmp12_);
1158 result = NULL;
1159 if (mask_out) {
1160 *mask_out = _vala_mask_out;
1161 }
1162 return result;
1163 }
1164 if (mask_out) {
1165 *mask_out = _vala_mask_out;
1166 }
1167 }
1168
1169 /**
1170 * Copy an object from atomic pointer.
1171 *
1172 * @param aptr Atomic pointer.
1173 * @param mask Mask of flags.
1174 * @param mask_out Result of mask.
1175 * @return A copy of object from atomic pointer.
1176 */
1177 gpointer
gee_hazard_pointer_get_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gsize mask,gsize * mask_out)1178 gee_hazard_pointer_get_pointer (GType g_type,
1179 GBoxedCopyFunc g_dup_func,
1180 GDestroyNotify g_destroy_func,
1181 gconstpointer** aptr,
1182 gsize mask,
1183 gsize* mask_out)
1184 {
1185 gsize _vala_mask_out = 0UL;
1186 GeeHazardPointerNode* node = NULL;
1187 GeeHazardPointerNode* _tmp0_;
1188 void* rptr = NULL;
1189 void* ptr = NULL;
1190 gpointer res = NULL;
1191 void* _tmp9_;
1192 gpointer _tmp10_;
1193 GeeHazardPointerNode* _tmp11_;
1194 gpointer result = NULL;
1195 _tmp0_ = gee_hazard_pointer_acquire ();
1196 node = _tmp0_;
1197 rptr = NULL;
1198 ptr = NULL;
1199 _vala_mask_out = (gsize) 0;
1200 {
1201 gboolean _tmp1_ = FALSE;
1202 _tmp1_ = TRUE;
1203 while (TRUE) {
1204 void* _tmp4_;
1205 void* _tmp5_;
1206 void* _tmp6_;
1207 GeeHazardPointerNode* _tmp7_;
1208 void* _tmp8_;
1209 if (!_tmp1_) {
1210 void* _tmp2_;
1211 void* _tmp3_;
1212 _tmp2_ = rptr;
1213 _tmp3_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) aptr));
1214 if (!(_tmp2_ != _tmp3_)) {
1215 break;
1216 }
1217 }
1218 _tmp1_ = FALSE;
1219 _tmp4_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) aptr));
1220 rptr = _tmp4_;
1221 _tmp5_ = rptr;
1222 ptr = (void*) (((gsize) _tmp5_) & (~mask));
1223 _tmp6_ = rptr;
1224 _vala_mask_out = ((gsize) _tmp6_) & mask;
1225 _tmp7_ = node;
1226 _tmp8_ = ptr;
1227 gee_hazard_pointer_node_set (_tmp7_, _tmp8_);
1228 }
1229 }
1230 _tmp9_ = ptr;
1231 _tmp10_ = ((((gconstpointer*) _tmp9_) != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) ((gconstpointer*) _tmp9_)) : ((gpointer) ((gconstpointer*) _tmp9_));
1232 res = _tmp10_;
1233 _tmp11_ = node;
1234 gee_hazard_pointer_node_release (_tmp11_);
1235 result = res;
1236 if (mask_out) {
1237 *mask_out = _vala_mask_out;
1238 }
1239 return result;
1240 }
1241
1242 /**
1243 * Exchange objects safly.
1244 *
1245 * @param aptr Atomic pointer.
1246 * @param new_ptr New value
1247 * @param mask Mask of flags.
1248 * @param new_mask New mask.
1249 * @param old_mask Previous mask mask.
1250 * @return Hazard pointer containing old value.
1251 */
1252 GeeHazardPointer*
gee_hazard_pointer_exchange_hazard_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gpointer new_ptr,gsize mask,gsize new_mask,gsize * old_mask)1253 gee_hazard_pointer_exchange_hazard_pointer (GType g_type,
1254 GBoxedCopyFunc g_dup_func,
1255 GDestroyNotify g_destroy_func,
1256 gconstpointer** aptr,
1257 gpointer new_ptr,
1258 gsize mask,
1259 gsize new_mask,
1260 gsize* old_mask)
1261 {
1262 gsize _vala_old_mask = 0UL;
1263 GeeHazardPointerNode* new_node = NULL;
1264 void* new_rptr = NULL;
1265 gpointer _tmp2_;
1266 GeeHazardPointerNode* node = NULL;
1267 GeeHazardPointerNode* _tmp3_;
1268 void* rptr = NULL;
1269 void* ptr = NULL;
1270 GeeHazardPointerNode* _tmp12_;
1271 void* _tmp14_;
1272 GeeHazardPointer* result = NULL;
1273 new_node = NULL;
1274 if (new_ptr != NULL) {
1275 GeeHazardPointerNode* _tmp0_;
1276 GeeHazardPointerNode* _tmp1_;
1277 _tmp0_ = gee_hazard_pointer_acquire ();
1278 new_node = _tmp0_;
1279 _tmp1_ = new_node;
1280 gee_hazard_pointer_node_set (_tmp1_, new_ptr);
1281 }
1282 _vala_old_mask = (gsize) 0;
1283 _tmp2_ = new_ptr;
1284 new_ptr = NULL;
1285 new_rptr = (void*) (((gsize) _tmp2_) | (mask & new_mask));
1286 _tmp3_ = gee_hazard_pointer_acquire ();
1287 node = _tmp3_;
1288 rptr = NULL;
1289 ptr = NULL;
1290 {
1291 gboolean _tmp4_ = FALSE;
1292 _tmp4_ = TRUE;
1293 while (TRUE) {
1294 void* _tmp7_;
1295 void* _tmp8_;
1296 void* _tmp9_;
1297 GeeHazardPointerNode* _tmp10_;
1298 void* _tmp11_;
1299 if (!_tmp4_) {
1300 void* _tmp5_;
1301 void* _tmp6_;
1302 _tmp5_ = rptr;
1303 _tmp6_ = new_rptr;
1304 if (!(!g_atomic_pointer_compare_and_exchange ((volatile gpointer *) ((void**) aptr), _tmp5_, _tmp6_))) {
1305 break;
1306 }
1307 }
1308 _tmp4_ = FALSE;
1309 _tmp7_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) aptr));
1310 rptr = _tmp7_;
1311 _tmp8_ = rptr;
1312 ptr = (void*) (((gsize) _tmp8_) & (~mask));
1313 _tmp9_ = rptr;
1314 _vala_old_mask = ((gsize) _tmp9_) & mask;
1315 _tmp10_ = node;
1316 _tmp11_ = ptr;
1317 gee_hazard_pointer_node_set (_tmp10_, _tmp11_);
1318 }
1319 }
1320 _tmp12_ = new_node;
1321 if (_tmp12_ != NULL) {
1322 GeeHazardPointerNode* _tmp13_;
1323 _tmp13_ = new_node;
1324 gee_hazard_pointer_node_release (_tmp13_);
1325 }
1326 _tmp14_ = ptr;
1327 if (_tmp14_ != NULL) {
1328 GeeHazardPointerNode* _tmp15_;
1329 GeeHazardPointer* _tmp16_;
1330 _tmp15_ = node;
1331 _tmp16_ = gee_hazard_pointer_new_from_node (_tmp15_);
1332 result = _tmp16_;
1333 _g_destroy_func0 (new_ptr);
1334 if (old_mask) {
1335 *old_mask = _vala_old_mask;
1336 }
1337 return result;
1338 } else {
1339 GeeHazardPointerNode* _tmp17_;
1340 _tmp17_ = node;
1341 gee_hazard_pointer_node_release (_tmp17_);
1342 result = NULL;
1343 _g_destroy_func0 (new_ptr);
1344 if (old_mask) {
1345 *old_mask = _vala_old_mask;
1346 }
1347 return result;
1348 }
1349 _g_destroy_func0 (new_ptr);
1350 if (old_mask) {
1351 *old_mask = _vala_old_mask;
1352 }
1353 }
1354
1355 /**
1356 * Sets object safely
1357 *
1358 * @param aptr Atomic pointer.
1359 * @param new_ptr New value
1360 * @param mask Mask of flags.
1361 * @param new_mask New mask.
1362 */
1363 void
gee_hazard_pointer_set_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gpointer new_ptr,gsize mask,gsize new_mask)1364 gee_hazard_pointer_set_pointer (GType g_type,
1365 GBoxedCopyFunc g_dup_func,
1366 GDestroyNotify g_destroy_func,
1367 gconstpointer** aptr,
1368 gpointer new_ptr,
1369 gsize mask,
1370 gsize new_mask)
1371 {
1372 GeeHazardPointer* ptr = NULL;
1373 gpointer _tmp0_;
1374 GeeHazardPointer* _tmp1_;
1375 GeeHazardPointer* _tmp2_;
1376 _tmp0_ = ((new_ptr != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) new_ptr) : ((gpointer) new_ptr);
1377 _tmp1_ = gee_hazard_pointer_exchange_hazard_pointer (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, aptr, _tmp0_, mask, new_mask, NULL);
1378 ptr = _tmp1_;
1379 _tmp2_ = ptr;
1380 if (_tmp2_ != NULL) {
1381 GDestroyNotify notify = NULL;
1382 GDestroyNotify _tmp3_;
1383 GDestroyNotify _tmp4_;
1384 _tmp3_ = gee_utils_free_get_destroy_notify (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
1385 notify = _tmp3_;
1386 _tmp4_ = notify;
1387 if (_tmp4_ != NULL) {
1388 GeeHazardPointer* _tmp5_;
1389 GDestroyNotify _tmp6_;
1390 _tmp5_ = ptr;
1391 _tmp6_ = notify;
1392 notify = NULL;
1393 gee_hazard_pointer_release (_tmp5_, _tmp6_);
1394 }
1395 }
1396 _gee_hazard_pointer_free0 (ptr);
1397 _g_destroy_func0 (new_ptr);
1398 }
1399
1400 /**
1401 * Exchange objects safly.
1402 *
1403 * @param aptr Atomic pointer.
1404 * @param new_ptr New value
1405 * @param mask Mask of flags.
1406 * @param new_mask New mask.
1407 * @param old_mask Previous mask mask.
1408 * @return Value that was previously stored.
1409 */
1410 gpointer
gee_hazard_pointer_exchange_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gpointer new_ptr,gsize mask,gsize new_mask,gsize * old_mask)1411 gee_hazard_pointer_exchange_pointer (GType g_type,
1412 GBoxedCopyFunc g_dup_func,
1413 GDestroyNotify g_destroy_func,
1414 gconstpointer** aptr,
1415 gpointer new_ptr,
1416 gsize mask,
1417 gsize new_mask,
1418 gsize* old_mask)
1419 {
1420 gsize _vala_old_mask = 0UL;
1421 GeeHazardPointer* ptr = NULL;
1422 gpointer _tmp0_;
1423 gsize _tmp1_ = 0UL;
1424 GeeHazardPointer* _tmp2_;
1425 gconstpointer _tmp3_ = NULL;
1426 GeeHazardPointer* _tmp4_;
1427 gpointer rptr = NULL;
1428 gpointer _tmp7_;
1429 gpointer result = NULL;
1430 _tmp0_ = ((new_ptr != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) new_ptr) : ((gpointer) new_ptr);
1431 _tmp2_ = gee_hazard_pointer_exchange_hazard_pointer (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, aptr, _tmp0_, mask, new_mask, &_tmp1_);
1432 _vala_old_mask = _tmp1_;
1433 ptr = _tmp2_;
1434 _tmp4_ = ptr;
1435 if (_tmp4_ != NULL) {
1436 GeeHazardPointer* _tmp5_;
1437 gconstpointer _tmp6_;
1438 _tmp5_ = ptr;
1439 _tmp6_ = gee_hazard_pointer_get (_tmp5_, FALSE);
1440 _tmp3_ = _tmp6_;
1441 } else {
1442 _tmp3_ = NULL;
1443 }
1444 _tmp7_ = ((_tmp3_ != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) _tmp3_) : ((gpointer) _tmp3_);
1445 rptr = _tmp7_;
1446 result = rptr;
1447 _gee_hazard_pointer_free0 (ptr);
1448 _g_destroy_func0 (new_ptr);
1449 if (old_mask) {
1450 *old_mask = _vala_old_mask;
1451 }
1452 return result;
1453 }
1454
1455 /**
1456 * Compares and exchanges objects.
1457 *
1458 * @param aptr Atomic pointer.
1459 * @param old_ptr Old pointer.
1460 * @param _new_ptr New value.
1461 * @param old_mask Old mask.
1462 * @param new_mask New mask.
1463 * @return Value that was previously stored.
1464 */
1465 gboolean
gee_hazard_pointer_compare_and_exchange_pointer(GType g_type,GBoxedCopyFunc g_dup_func,GDestroyNotify g_destroy_func,gconstpointer ** aptr,gconstpointer old_ptr,gpointer _new_ptr,gsize mask,gsize old_mask,gsize new_mask)1466 gee_hazard_pointer_compare_and_exchange_pointer (GType g_type,
1467 GBoxedCopyFunc g_dup_func,
1468 GDestroyNotify g_destroy_func,
1469 gconstpointer** aptr,
1470 gconstpointer old_ptr,
1471 gpointer _new_ptr,
1472 gsize mask,
1473 gsize old_mask,
1474 gsize new_mask)
1475 {
1476 gconstpointer* new_ptr = NULL;
1477 gpointer _tmp0_;
1478 void* new_rptr = NULL;
1479 gconstpointer* _tmp1_;
1480 void* old_rptr = NULL;
1481 gboolean success = FALSE;
1482 void* _tmp2_;
1483 void* _tmp3_;
1484 gboolean result = FALSE;
1485 _tmp0_ = _new_ptr;
1486 _new_ptr = NULL;
1487 new_ptr = _tmp0_;
1488 _tmp1_ = new_ptr;
1489 new_rptr = (void*) (((gsize) _tmp1_) | (mask & new_mask));
1490 old_rptr = (void*) (((gsize) old_ptr) | (mask & old_mask));
1491 _tmp2_ = old_rptr;
1492 _tmp3_ = new_rptr;
1493 success = g_atomic_pointer_compare_and_exchange ((volatile gpointer *) ((void**) aptr), _tmp2_, _tmp3_);
1494 if (success) {
1495 GDestroyNotify notify = NULL;
1496 GDestroyNotify _tmp4_;
1497 gboolean _tmp5_ = FALSE;
1498 _tmp4_ = gee_utils_free_get_destroy_notify (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
1499 notify = _tmp4_;
1500 if (old_ptr != NULL) {
1501 GDestroyNotify _tmp6_;
1502 _tmp6_ = notify;
1503 _tmp5_ = _tmp6_ != NULL;
1504 } else {
1505 _tmp5_ = FALSE;
1506 }
1507 if (_tmp5_) {
1508 GeeHazardPointerContext* _tmp7_;
1509 GDestroyNotify _tmp8_;
1510 _tmp7_ = gee_hazard_pointer_context_get_current_context ();
1511 _tmp8_ = notify;
1512 notify = NULL;
1513 gee_hazard_pointer_context_release_ptr (_tmp7_, old_ptr, _tmp8_);
1514 }
1515 } else {
1516 gconstpointer* _tmp9_;
1517 _tmp9_ = new_ptr;
1518 if (_tmp9_ != NULL) {
1519 gconstpointer* _tmp10_;
1520 _tmp10_ = new_ptr;
1521 new_ptr = NULL;
1522 _g_destroy_func0 (_new_ptr);
1523 _new_ptr = _tmp10_;
1524 }
1525 }
1526 result = success;
1527 _g_destroy_func0 (_new_ptr);
1528 return result;
1529 }
1530
1531 /**
1532 * Gets the pointer hold by hazard pointer.
1533 *
1534 * @param other_thread Have to be set to ``true`` if accessed from thread that did not create this thread.
1535 * @return The value hold by pointer.
1536 */
1537 inline gconstpointer
gee_hazard_pointer_get(GeeHazardPointer * self,gboolean other_thread)1538 gee_hazard_pointer_get (GeeHazardPointer* self,
1539 gboolean other_thread)
1540 {
1541 GeeHazardPointerNode* _tmp0_;
1542 void* _tmp1_;
1543 gconstpointer result = NULL;
1544 g_return_val_if_fail (self != NULL, NULL);
1545 _tmp0_ = self->_node;
1546 _tmp1_ = gee_hazard_pointer_node_get (_tmp0_, other_thread);
1547 result = _tmp1_;
1548 return result;
1549 }
1550
1551 /**
1552 * Free the pointer.
1553 *
1554 * @param notify method freeing object
1555 */
1556 void
gee_hazard_pointer_release(GeeHazardPointer * self,GDestroyNotify notify)1557 gee_hazard_pointer_release (GeeHazardPointer* self,
1558 GDestroyNotify notify)
1559 {
1560 gconstpointer item = NULL;
1561 GeeHazardPointerNode* _tmp0_;
1562 void* _tmp1_;
1563 GeeHazardPointerNode* _tmp2_;
1564 gconstpointer _tmp3_;
1565 g_return_if_fail (self != NULL);
1566 _tmp0_ = self->_node;
1567 _tmp1_ = gee_hazard_pointer_node_get (_tmp0_, FALSE);
1568 item = _tmp1_;
1569 _tmp2_ = self->_node;
1570 gee_hazard_pointer_node_set (_tmp2_, NULL);
1571 _tmp3_ = item;
1572 if (_tmp3_ != NULL) {
1573 GeeHazardPointerContext* _tmp4_;
1574 gconstpointer _tmp5_;
1575 GDestroyNotify _tmp6_;
1576 _tmp4_ = gee_hazard_pointer_context_get_current_context ();
1577 _tmp5_ = item;
1578 _tmp6_ = notify;
1579 notify = NULL;
1580 gee_hazard_pointer_context_release_ptr (_tmp4_, _tmp5_, _tmp6_);
1581 }
1582 }
1583
1584 /**
1585 * Sets default policy (i.e. default policy for user-created contexts).
1586 * The policy must be concrete and should not be blocking.
1587 *
1588 * @param policy New default policy.
1589 */
1590 void
gee_hazard_pointer_set_default_policy(GeeHazardPointerPolicy policy)1591 gee_hazard_pointer_set_default_policy (GeeHazardPointerPolicy policy)
1592 {
1593 _vala_return_if_fail (gee_hazard_pointer_policy_is_concrete (policy), "policy.is_concrete ()");
1594 if (gee_hazard_pointer_policy_is_blocking (policy)) {
1595 g_warning ("hazardpointer.vala:252: Setting blocking defautl Gee.HazardPointer.Pol" \
1596 "icy (there may be a deadlock).\n");
1597 }
1598 g_atomic_int_set ((volatile gint *) (&gee_hazard_pointer__default_policy), (gint) policy);
1599 }
1600
1601 /**
1602 * Sets thread exit policy (i.e. default policy for the top-most Context).
1603 * The policy must be concrete and should not be unsafe.
1604 *
1605 * @param policy New thread policy.
1606 */
1607 void
gee_hazard_pointer_set_thread_exit_policy(GeeHazardPointerPolicy policy)1608 gee_hazard_pointer_set_thread_exit_policy (GeeHazardPointerPolicy policy)
1609 {
1610 _vala_return_if_fail (gee_hazard_pointer_policy_is_concrete (policy), "policy.is_concrete ()");
1611 if (!gee_hazard_pointer_policy_is_safe (policy)) {
1612 g_warning ("hazardpointer.vala:264: Setting unsafe globale thread-exit Gee.HazardP" \
1613 "ointer.Policy (there may be a memory leak).\n");
1614 }
1615 g_atomic_int_set ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy), (gint) policy);
1616 }
1617
1618 /**
1619 * Sets release (i.e. how exactly the released objects arefreed).
1620 *
1621 * The method can be only set before any objects is released and is not thread-safe.
1622 *
1623 * @param policy New release policy.
1624 */
1625 gboolean
gee_hazard_pointer_set_release_policy(GeeHazardPointerReleasePolicy policy)1626 gee_hazard_pointer_set_release_policy (GeeHazardPointerReleasePolicy policy)
1627 {
1628 gint old_policy = 0;
1629 gint _tmp0_;
1630 gboolean _tmp1_;
1631 gboolean result = FALSE;
1632 _tmp0_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
1633 old_policy = _tmp0_;
1634 if ((old_policy & ((sizeof (gint) * 8) - 1)) != 0) {
1635 g_critical ("hazardpointer.vala:278: Attempt to change the policy of running helper" \
1636 ". Failing.");
1637 result = FALSE;
1638 return result;
1639 }
1640 _tmp1_ = g_atomic_int_compare_and_exchange ((volatile gint *) (&gee_hazard_pointer_release_policy), old_policy, (gint) policy);
1641 if (!_tmp1_) {
1642 g_critical ("hazardpointer.vala:282: Concurrent access to release policy detected. " \
1643 "Failing.");
1644 result = FALSE;
1645 return result;
1646 }
1647 result = TRUE;
1648 return result;
1649 }
1650
1651 /**
1652 * Gets a new hazard pointer node.
1653 *
1654 * @return new hazard pointer node.
1655 */
1656 G_GNUC_INTERNAL inline GeeHazardPointerNode*
gee_hazard_pointer_acquire(void)1657 gee_hazard_pointer_acquire (void)
1658 {
1659 GeeHazardPointerNode* node = NULL;
1660 GeeHazardPointerNode* _tmp7_;
1661 GeeHazardPointerNode* old_head = NULL;
1662 GeeHazardPointerNode* _tmp14_;
1663 GeeHazardPointerNode* result = NULL;
1664 {
1665 GeeHazardPointerNode* curr = NULL;
1666 GeeHazardPointerNode* _tmp0_;
1667 _tmp0_ = gee_hazard_pointer_get_head ();
1668 curr = _tmp0_;
1669 {
1670 gboolean _tmp1_ = FALSE;
1671 _tmp1_ = TRUE;
1672 while (TRUE) {
1673 GeeHazardPointerNode* _tmp4_;
1674 GeeHazardPointerNode* _tmp5_;
1675 if (!_tmp1_) {
1676 GeeHazardPointerNode* _tmp2_;
1677 GeeHazardPointerNode* _tmp3_;
1678 _tmp2_ = curr;
1679 _tmp3_ = gee_hazard_pointer_node_get_next (_tmp2_);
1680 curr = _tmp3_;
1681 }
1682 _tmp1_ = FALSE;
1683 _tmp4_ = curr;
1684 if (!(_tmp4_ != NULL)) {
1685 break;
1686 }
1687 _tmp5_ = curr;
1688 if (gee_hazard_pointer_node_activate (_tmp5_)) {
1689 GeeHazardPointerNode* _tmp6_;
1690 _tmp6_ = curr;
1691 result = _tmp6_;
1692 return result;
1693 }
1694 }
1695 }
1696 }
1697 _tmp7_ = gee_hazard_pointer_node_new ();
1698 node = _tmp7_;
1699 old_head = NULL;
1700 {
1701 gboolean _tmp8_ = FALSE;
1702 _tmp8_ = TRUE;
1703 while (TRUE) {
1704 GeeHazardPointerNode* _tmp11_;
1705 void* _tmp12_;
1706 GeeHazardPointerNode* _tmp13_;
1707 if (!_tmp8_) {
1708 GeeHazardPointerNode* _tmp9_;
1709 GeeHazardPointerNode* _tmp10_;
1710 _tmp9_ = old_head;
1711 _tmp10_ = node;
1712 if (!(!g_atomic_pointer_compare_and_exchange ((volatile gpointer *) (&gee_hazard_pointer__head), _tmp9_, _tmp10_))) {
1713 break;
1714 }
1715 }
1716 _tmp8_ = FALSE;
1717 _tmp11_ = node;
1718 _tmp12_ = g_atomic_pointer_get ((volatile gpointer *) (&gee_hazard_pointer__head));
1719 old_head = (GeeHazardPointerNode*) _tmp12_;
1720 _tmp13_ = old_head;
1721 gee_hazard_pointer_node_set_next (_tmp11_, _tmp13_);
1722 }
1723 }
1724 _tmp14_ = node;
1725 result = _tmp14_;
1726 return result;
1727 }
1728
1729 /**
1730 * Tries to free from list.
1731 *
1732 * @return ``true`` if list is empty.
1733 */
1734 G_GNUC_INTERNAL gboolean
gee_hazard_pointer_try_free(GeeArrayList * to_free)1735 gee_hazard_pointer_try_free (GeeArrayList* to_free)
1736 {
1737 GeeCollection* used = NULL;
1738 GeeHashSet* _tmp0_;
1739 gint _tmp30_;
1740 gint _tmp31_;
1741 gboolean result = FALSE;
1742 g_return_val_if_fail (to_free != NULL, FALSE);
1743 _tmp0_ = gee_hash_set_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1744 used = (GeeCollection*) _tmp0_;
1745 {
1746 GeeHazardPointerNode* current = NULL;
1747 GeeHazardPointerNode* _tmp1_;
1748 _tmp1_ = gee_hazard_pointer_get_head ();
1749 current = _tmp1_;
1750 {
1751 gboolean _tmp2_ = FALSE;
1752 _tmp2_ = TRUE;
1753 while (TRUE) {
1754 GeeHazardPointerNode* _tmp5_;
1755 GeeCollection* _tmp6_;
1756 GeeHazardPointerNode* _tmp7_;
1757 void* _tmp8_;
1758 if (!_tmp2_) {
1759 GeeHazardPointerNode* _tmp3_;
1760 GeeHazardPointerNode* _tmp4_;
1761 _tmp3_ = current;
1762 _tmp4_ = gee_hazard_pointer_node_get_next (_tmp3_);
1763 current = _tmp4_;
1764 }
1765 _tmp2_ = FALSE;
1766 _tmp5_ = current;
1767 if (!(_tmp5_ != NULL)) {
1768 break;
1769 }
1770 _tmp6_ = used;
1771 _tmp7_ = current;
1772 _tmp8_ = gee_hazard_pointer_node_get (_tmp7_, TRUE);
1773 gee_collection_add (_tmp6_, _tmp8_);
1774 }
1775 }
1776 }
1777 {
1778 gint i = 0;
1779 i = 0;
1780 {
1781 gboolean _tmp9_ = FALSE;
1782 _tmp9_ = TRUE;
1783 while (TRUE) {
1784 gint _tmp10_;
1785 gint _tmp11_;
1786 GeeHazardPointerFreeNode* current = NULL;
1787 gpointer _tmp12_;
1788 GeeCollection* _tmp13_;
1789 GeeHazardPointerFreeNode* _tmp14_;
1790 void* _tmp15_;
1791 if (!_tmp9_) {
1792 }
1793 _tmp9_ = FALSE;
1794 _tmp10_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) to_free);
1795 _tmp11_ = _tmp10_;
1796 if (!(i < _tmp11_)) {
1797 break;
1798 }
1799 _tmp12_ = gee_abstract_list_get ((GeeAbstractList*) to_free, i);
1800 current = _tmp12_;
1801 _tmp13_ = used;
1802 _tmp14_ = current;
1803 _tmp15_ = _tmp14_->pointer;
1804 if (gee_collection_contains (_tmp13_, _tmp15_)) {
1805 gint _tmp16_;
1806 _tmp16_ = i;
1807 i = _tmp16_ + 1;
1808 } else {
1809 GeeHazardPointerFreeNode* cur = NULL;
1810 gint _tmp17_;
1811 gint _tmp18_;
1812 gpointer _tmp19_;
1813 gint _tmp20_;
1814 gint _tmp21_;
1815 GeeHazardPointerFreeNode* _tmp25_;
1816 GDestroyNotify _tmp26_;
1817 GeeHazardPointerFreeNode* _tmp27_;
1818 void* _tmp28_;
1819 GeeHazardPointerFreeNode* _tmp29_;
1820 _tmp17_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) to_free);
1821 _tmp18_ = _tmp17_;
1822 _tmp19_ = gee_abstract_list_remove_at ((GeeAbstractList*) to_free, _tmp18_ - 1);
1823 cur = _tmp19_;
1824 _tmp20_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) to_free);
1825 _tmp21_ = _tmp20_;
1826 if (i != _tmp21_) {
1827 GeeHazardPointerFreeNode* temp = NULL;
1828 gpointer _tmp22_;
1829 GeeHazardPointerFreeNode* _tmp23_;
1830 GeeHazardPointerFreeNode* _tmp24_;
1831 _tmp22_ = gee_abstract_list_get ((GeeAbstractList*) to_free, i);
1832 temp = _tmp22_;
1833 _tmp23_ = cur;
1834 gee_abstract_list_set ((GeeAbstractList*) to_free, i, _tmp23_);
1835 _tmp24_ = temp;
1836 cur = _tmp24_;
1837 }
1838 _tmp25_ = cur;
1839 _tmp26_ = _tmp25_->destroy_notify;
1840 _tmp27_ = cur;
1841 _tmp28_ = _tmp27_->pointer;
1842 _tmp26_ (_tmp28_);
1843 _tmp29_ = cur;
1844 gee_hazard_pointer_free_node_free (_tmp29_);
1845 }
1846 }
1847 }
1848 }
1849 _tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) to_free);
1850 _tmp31_ = _tmp30_;
1851 result = _tmp31_ > 0;
1852 _g_object_unref0 (used);
1853 return result;
1854 }
1855
1856 /**
1857 * Gets head of hazard pointers.
1858 * @return Hazard pointer head.
1859 */
1860 G_GNUC_INTERNAL GeeHazardPointerNode*
gee_hazard_pointer_get_head(void)1861 gee_hazard_pointer_get_head (void)
1862 {
1863 void* _tmp0_;
1864 GeeHazardPointerNode* result = NULL;
1865 _tmp0_ = g_atomic_pointer_get ((volatile gpointer *) (&gee_hazard_pointer__head));
1866 result = (GeeHazardPointerNode*) _tmp0_;
1867 return result;
1868 }
1869
1870 static GeeHazardPointerPolicy*
_gee_hazard_pointer_policy_dup(GeeHazardPointerPolicy * self)1871 _gee_hazard_pointer_policy_dup (GeeHazardPointerPolicy* self)
1872 {
1873 GeeHazardPointerPolicy* dup;
1874 dup = g_new0 (GeeHazardPointerPolicy, 1);
1875 memcpy (dup, self, sizeof (GeeHazardPointerPolicy));
1876 return dup;
1877 }
1878
1879 static gpointer
__gee_hazard_pointer_policy_dup0(gpointer self)1880 __gee_hazard_pointer_policy_dup0 (gpointer self)
1881 {
1882 return self ? _gee_hazard_pointer_policy_dup (self) : NULL;
1883 }
1884
1885 GeeHazardPointerContext*
gee_hazard_pointer_context_new(GeeHazardPointerPolicy * policy)1886 gee_hazard_pointer_context_new (GeeHazardPointerPolicy* policy)
1887 {
1888 GeeHazardPointerContext* self;
1889 GeeArrayList* _tmp0_;
1890 void* _tmp1_;
1891 self = g_slice_new0 (GeeHazardPointerContext);
1892 gee_hazard_pointer_context_instance_init (self);
1893 _tmp0_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
1894 _g_object_unref0 (self->_to_free);
1895 self->_to_free = _tmp0_;
1896 _tmp1_ = g_static_private_get (&gee_hazard_pointer_context__current_context);
1897 self->_parent = _tmp1_;
1898 g_static_private_set (&gee_hazard_pointer_context__current_context, self, NULL);
1899 if (policy == NULL) {
1900 GeeHazardPointerContext* _tmp2_;
1901 _tmp2_ = self->_parent;
1902 if (_tmp2_ == NULL) {
1903 gint _tmp3_;
1904 GeeHazardPointerPolicy _tmp4_;
1905 GeeHazardPointerPolicy* _tmp5_;
1906 _tmp3_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy));
1907 _tmp4_ = (GeeHazardPointerPolicy) _tmp3_;
1908 _tmp5_ = __gee_hazard_pointer_policy_dup0 (&_tmp4_);
1909 _g_free0 (self->_policy);
1910 self->_policy = _tmp5_;
1911 } else {
1912 gint _tmp6_;
1913 GeeHazardPointerPolicy _tmp7_;
1914 GeeHazardPointerPolicy* _tmp8_;
1915 _tmp6_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__default_policy));
1916 _tmp7_ = (GeeHazardPointerPolicy) _tmp6_;
1917 _tmp8_ = __gee_hazard_pointer_policy_dup0 (&_tmp7_);
1918 _g_free0 (self->_policy);
1919 self->_policy = _tmp8_;
1920 }
1921 } else {
1922 GeeHazardPointerPolicy _tmp9_;
1923 GeeHazardPointerPolicy* _tmp10_;
1924 _tmp9_ = gee_hazard_pointer_policy_to_concrete (*policy);
1925 _tmp10_ = __gee_hazard_pointer_policy_dup0 (&_tmp9_);
1926 _g_free0 (self->_policy);
1927 self->_policy = _tmp10_;
1928 }
1929 return self;
1930 }
1931
1932 /**
1933 * Tries to free all freed pointer in current context.
1934 */
1935 void
gee_hazard_pointer_context_try_free(GeeHazardPointerContext * self)1936 gee_hazard_pointer_context_try_free (GeeHazardPointerContext* self)
1937 {
1938 GeeArrayList* _tmp0_;
1939 g_return_if_fail (self != NULL);
1940 _tmp0_ = self->_to_free;
1941 gee_hazard_pointer_try_free (_tmp0_);
1942 }
1943
1944 /**
1945 * Ensure that whole context is freed. Plase note that it might block.
1946 */
1947 void
gee_hazard_pointer_context_free_all(GeeHazardPointerContext * self)1948 gee_hazard_pointer_context_free_all (GeeHazardPointerContext* self)
1949 {
1950 g_return_if_fail (self != NULL);
1951 while (TRUE) {
1952 GeeArrayList* _tmp0_;
1953 _tmp0_ = self->_to_free;
1954 if (!gee_hazard_pointer_try_free (_tmp0_)) {
1955 break;
1956 }
1957 g_thread_yield ();
1958 }
1959 }
1960
1961 /**
1962 * Tries to push the current context to releaser.
1963 */
1964 void
gee_hazard_pointer_context_try_release(GeeHazardPointerContext * self)1965 gee_hazard_pointer_context_try_release (GeeHazardPointerContext* self)
1966 {
1967 g_return_if_fail (self != NULL);
1968 if (g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex)) {
1969 GeeQueue* _tmp0_;
1970 GeeArrayList* _tmp1_;
1971 GeeArrayList* _tmp2_;
1972 GeeArrayList* _tmp3_;
1973 _tmp0_ = gee_hazard_pointer__queue;
1974 _tmp1_ = self->_to_free;
1975 self->_to_free = NULL;
1976 _tmp2_ = _tmp1_;
1977 gee_queue_offer (_tmp0_, _tmp2_);
1978 _g_object_unref0 (_tmp2_);
1979 _tmp3_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
1980 _g_object_unref0 (self->_to_free);
1981 self->_to_free = _tmp3_;
1982 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
1983 }
1984 }
1985
1986 /**
1987 * Pushes the current context to releaser. Plase note that it might block.
1988 */
1989 void
gee_hazard_pointer_context_release(GeeHazardPointerContext * self)1990 gee_hazard_pointer_context_release (GeeHazardPointerContext* self)
1991 {
1992 GeeQueue* _tmp0_;
1993 GeeArrayList* _tmp1_;
1994 GeeArrayList* _tmp2_;
1995 GeeArrayList* _tmp3_;
1996 g_return_if_fail (self != NULL);
1997 g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
1998 _tmp0_ = gee_hazard_pointer__queue;
1999 _tmp1_ = self->_to_free;
2000 self->_to_free = NULL;
2001 _tmp2_ = _tmp1_;
2002 gee_queue_offer (_tmp0_, _tmp2_);
2003 _g_object_unref0 (_tmp2_);
2004 _tmp3_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
2005 _g_object_unref0 (self->_to_free);
2006 self->_to_free = _tmp3_;
2007 g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
2008 }
2009
2010 /**
2011 * Add pointer to freed array.
2012 */
2013 G_GNUC_INTERNAL inline void
gee_hazard_pointer_context_release_ptr(GeeHazardPointerContext * self,void * ptr,GDestroyNotify notify)2014 gee_hazard_pointer_context_release_ptr (GeeHazardPointerContext* self,
2015 void* ptr,
2016 GDestroyNotify notify)
2017 {
2018 GeeHazardPointerFreeNode* node = NULL;
2019 GeeHazardPointerFreeNode* _tmp0_;
2020 GeeHazardPointerFreeNode* _tmp1_;
2021 GeeHazardPointerFreeNode* _tmp2_;
2022 GDestroyNotify _tmp3_;
2023 GeeArrayList* _tmp4_;
2024 GeeHazardPointerFreeNode* _tmp5_;
2025 GeeArrayList* _tmp6_;
2026 gint _tmp7_;
2027 gint _tmp8_;
2028 g_return_if_fail (self != NULL);
2029 _tmp0_ = gee_hazard_pointer_free_node_new ();
2030 node = _tmp0_;
2031 _tmp1_ = node;
2032 _tmp1_->pointer = ptr;
2033 _tmp2_ = node;
2034 _tmp3_ = notify;
2035 notify = NULL;
2036 _tmp2_->destroy_notify = _tmp3_;
2037 _tmp4_ = self->_to_free;
2038 _tmp5_ = node;
2039 gee_abstract_collection_add ((GeeAbstractCollection*) _tmp4_, _tmp5_);
2040 _tmp6_ = self->_to_free;
2041 _tmp7_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp6_);
2042 _tmp8_ = _tmp7_;
2043 if (((guint) _tmp8_) >= gee_hazard_pointer_context_THRESHOLD) {
2044 GeeArrayList* _tmp9_;
2045 _tmp9_ = self->_to_free;
2046 gee_hazard_pointer_try_free (_tmp9_);
2047 }
2048 }
2049
2050 /**
2051 * Gets current context.
2052 */
2053 G_GNUC_INTERNAL inline GeeHazardPointerContext*
gee_hazard_pointer_context_get_current_context(void)2054 gee_hazard_pointer_context_get_current_context (void)
2055 {
2056 void* _tmp0_;
2057 GeeHazardPointerContext* result = NULL;
2058 _tmp0_ = g_static_private_get (&gee_hazard_pointer_context__current_context);
2059 result = _tmp0_;
2060 return result;
2061 }
2062
2063 static void
gee_hazard_pointer_context_instance_init(GeeHazardPointerContext * self)2064 gee_hazard_pointer_context_instance_init (GeeHazardPointerContext * self)
2065 {
2066 }
2067
2068 void
gee_hazard_pointer_context_free(GeeHazardPointerContext * self)2069 gee_hazard_pointer_context_free (GeeHazardPointerContext * self)
2070 {
2071 gint size = 0;
2072 GeeArrayList* _tmp0_;
2073 gint _tmp1_;
2074 gint _tmp2_;
2075 gboolean clean_parent = FALSE;
2076 GeeHazardPointerContext* _tmp13_;
2077 _tmp0_ = self->_to_free;
2078 _tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
2079 _tmp2_ = _tmp1_;
2080 size = _tmp2_;
2081 clean_parent = FALSE;
2082 if (size > 0) {
2083 gboolean _tmp3_ = FALSE;
2084 GeeHazardPointerContext* _tmp4_;
2085 _tmp4_ = self->_parent;
2086 if (_tmp4_ == NULL) {
2087 _tmp3_ = TRUE;
2088 } else {
2089 _tmp3_ = ((guint) size) >= gee_hazard_pointer_context_THRESHOLD;
2090 }
2091 if (_tmp3_) {
2092 GeeHazardPointerPolicy* _tmp5_;
2093 gboolean _tmp6_;
2094 _tmp5_ = self->_policy;
2095 _tmp6_ = gee_hazard_pointer_policy_perform (*_tmp5_, &self->_to_free);
2096 if (!_tmp6_) {
2097 gboolean _tmp7_ = FALSE;
2098 GeeHazardPointerContext* _tmp8_;
2099 GeeHazardPointerContext* _tmp10_;
2100 GeeArrayList* _tmp11_;
2101 GeeArrayList* _tmp12_;
2102 _tmp8_ = self->_parent;
2103 if (_tmp8_ != NULL) {
2104 GeeArrayList* _tmp9_;
2105 _tmp9_ = self->_to_free;
2106 _tmp7_ = _tmp9_ != NULL;
2107 } else {
2108 _tmp7_ = FALSE;
2109 }
2110 _vala_assert (_tmp7_, "_parent != null && _to_free != null");
2111 _tmp10_ = self->_parent;
2112 _tmp11_ = _tmp10_->_to_free;
2113 _tmp12_ = self->_to_free;
2114 gee_array_list_add_all (_tmp11_, (GeeCollection*) _tmp12_);
2115 clean_parent = TRUE;
2116 }
2117 }
2118 }
2119 _tmp13_ = self->_parent;
2120 g_static_private_set (&gee_hazard_pointer_context__current_context, _tmp13_, NULL);
2121 if (clean_parent) {
2122 GeeHazardPointerContext* _tmp14_;
2123 GeeArrayList* _tmp15_;
2124 _tmp14_ = self->_parent;
2125 _tmp15_ = _tmp14_->_to_free;
2126 gee_hazard_pointer_try_free (_tmp15_);
2127 }
2128 _g_object_unref0 (self->_to_free);
2129 _g_free0 (self->_policy);
2130 g_slice_free (GeeHazardPointerContext, self);
2131 }
2132
2133 G_GNUC_INTERNAL GeeHazardPointerFreeNode*
gee_hazard_pointer_free_node_new(void)2134 gee_hazard_pointer_free_node_new (void)
2135 {
2136 GeeHazardPointerFreeNode* self;
2137 self = g_slice_new0 (GeeHazardPointerFreeNode);
2138 gee_hazard_pointer_free_node_instance_init (self);
2139 return self;
2140 }
2141
2142 static void
gee_hazard_pointer_free_node_instance_init(GeeHazardPointerFreeNode * self)2143 gee_hazard_pointer_free_node_instance_init (GeeHazardPointerFreeNode * self)
2144 {
2145 }
2146
2147 G_GNUC_INTERNAL void
gee_hazard_pointer_free_node_free(GeeHazardPointerFreeNode * self)2148 gee_hazard_pointer_free_node_free (GeeHazardPointerFreeNode * self)
2149 {
2150 g_slice_free (GeeHazardPointerFreeNode, self);
2151 }
2152
2153 G_GNUC_INTERNAL GeeHazardPointerNode*
gee_hazard_pointer_node_new(void)2154 gee_hazard_pointer_node_new (void)
2155 {
2156 GeeHazardPointerNode* self;
2157 self = g_slice_new0 (GeeHazardPointerNode);
2158 gee_hazard_pointer_node_instance_init (self);
2159 g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), NULL);
2160 g_atomic_int_set ((volatile gint *) (&self->_active), 1);
2161 return self;
2162 }
2163
2164 G_GNUC_INTERNAL void
gee_hazard_pointer_node_release(GeeHazardPointerNode * self)2165 gee_hazard_pointer_node_release (GeeHazardPointerNode* self)
2166 {
2167 g_return_if_fail (self != NULL);
2168 g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), NULL);
2169 g_atomic_int_set ((volatile gint *) (&self->_active), 0);
2170 }
2171
2172 G_GNUC_INTERNAL inline gboolean
gee_hazard_pointer_node_is_active(GeeHazardPointerNode * self)2173 gee_hazard_pointer_node_is_active (GeeHazardPointerNode* self)
2174 {
2175 gint _tmp0_;
2176 gboolean result = FALSE;
2177 g_return_val_if_fail (self != NULL, FALSE);
2178 _tmp0_ = g_atomic_int_get ((volatile gint *) (&self->_active));
2179 result = _tmp0_ != 0;
2180 return result;
2181 }
2182
2183 G_GNUC_INTERNAL inline gboolean
gee_hazard_pointer_node_activate(GeeHazardPointerNode * self)2184 gee_hazard_pointer_node_activate (GeeHazardPointerNode* self)
2185 {
2186 gboolean _tmp0_;
2187 gboolean result = FALSE;
2188 g_return_val_if_fail (self != NULL, FALSE);
2189 _tmp0_ = g_atomic_int_compare_and_exchange ((volatile gint *) (&self->_active), 0, 1);
2190 result = _tmp0_;
2191 return result;
2192 }
2193
2194 G_GNUC_INTERNAL inline void
gee_hazard_pointer_node_set(GeeHazardPointerNode * self,void * ptr)2195 gee_hazard_pointer_node_set (GeeHazardPointerNode* self,
2196 void* ptr)
2197 {
2198 g_return_if_fail (self != NULL);
2199 g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), ptr);
2200 }
2201
2202 G_GNUC_INTERNAL inline void*
gee_hazard_pointer_node_get(GeeHazardPointerNode * self,gboolean safe)2203 gee_hazard_pointer_node_get (GeeHazardPointerNode* self,
2204 gboolean safe)
2205 {
2206 void* result = NULL;
2207 g_return_val_if_fail (self != NULL, NULL);
2208 if (safe) {
2209 void* _tmp0_;
2210 _tmp0_ = g_atomic_pointer_get ((volatile gpointer *) (&self->_hazard));
2211 result = (void*) _tmp0_;
2212 return result;
2213 } else {
2214 void* _tmp1_;
2215 _tmp1_ = self->_hazard;
2216 result = (void*) _tmp1_;
2217 return result;
2218 }
2219 }
2220
2221 G_GNUC_INTERNAL inline GeeHazardPointerNode*
gee_hazard_pointer_node_get_next(GeeHazardPointerNode * self)2222 gee_hazard_pointer_node_get_next (GeeHazardPointerNode* self)
2223 {
2224 void* _tmp0_;
2225 GeeHazardPointerNode* result = NULL;
2226 g_return_val_if_fail (self != NULL, NULL);
2227 _tmp0_ = g_atomic_pointer_get ((volatile gpointer *) (&self->_next));
2228 result = (GeeHazardPointerNode*) _tmp0_;
2229 return result;
2230 }
2231
2232 G_GNUC_INTERNAL inline void
gee_hazard_pointer_node_set_next(GeeHazardPointerNode * self,GeeHazardPointerNode * next)2233 gee_hazard_pointer_node_set_next (GeeHazardPointerNode* self,
2234 GeeHazardPointerNode* next)
2235 {
2236 g_return_if_fail (self != NULL);
2237 g_atomic_pointer_set ((volatile gpointer *) (&self->_next), next);
2238 }
2239
2240 static void
gee_hazard_pointer_node_instance_init(GeeHazardPointerNode * self)2241 gee_hazard_pointer_node_instance_init (GeeHazardPointerNode * self)
2242 {
2243 }
2244
2245 G_GNUC_INTERNAL void
gee_hazard_pointer_node_free(GeeHazardPointerNode * self)2246 gee_hazard_pointer_node_free (GeeHazardPointerNode * self)
2247 {
2248 GeeHazardPointerNode* _tmp0_;
2249 _tmp0_ = self->_next;
2250 gee_hazard_pointer_node_free (_tmp0_);
2251 g_slice_free (GeeHazardPointerNode, self);
2252 }
2253
2254 static void
gee_hazard_pointer_instance_init(GeeHazardPointer * self)2255 gee_hazard_pointer_instance_init (GeeHazardPointer * self)
2256 {
2257 }
2258
2259 void
gee_hazard_pointer_free(GeeHazardPointer * self)2260 gee_hazard_pointer_free (GeeHazardPointer * self)
2261 {
2262 GeeHazardPointerNode* _tmp0_;
2263 _tmp0_ = self->_node;
2264 gee_hazard_pointer_node_release (_tmp0_);
2265 g_slice_free (GeeHazardPointer, self);
2266 }
2267
2268