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