/* hazardpointer.c generated by valac 0.27.1.26-9b1a5, the Vala compiler
 * generated from hazardpointer.vala, do not modify */

/* hazardpointer.vala
 *
 * Copyright (C) 2011  Maciej Piechotka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Maciej Piechotka <uzytkownik2@gmail.com>
 */

#include <glib.h>
#include <glib-object.h>
#include <free.h>
#include <string.h>

typedef struct _GeeHazardPointer GeeHazardPointer;
typedef struct _GeeHazardPointerNode GeeHazardPointerNode;

#define GEE_HAZARD_POINTER_TYPE_POLICY (gee_hazard_pointer_policy_get_type ())

#define GEE_TYPE_ABSTRACT_COLLECTION (gee_abstract_collection_get_type ())
#define GEE_ABSTRACT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection))
#define GEE_ABSTRACT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollectionClass))
#define GEE_IS_ABSTRACT_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_COLLECTION))
#define GEE_IS_ABSTRACT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_COLLECTION))
#define GEE_ABSTRACT_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollectionClass))

typedef struct _GeeAbstractCollection GeeAbstractCollection;
typedef struct _GeeAbstractCollectionClass GeeAbstractCollectionClass;

#define GEE_TYPE_ABSTRACT_LIST (gee_abstract_list_get_type ())
#define GEE_ABSTRACT_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_LIST, GeeAbstractList))
#define GEE_ABSTRACT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_LIST, GeeAbstractListClass))
#define GEE_IS_ABSTRACT_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_LIST))
#define GEE_IS_ABSTRACT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_LIST))
#define GEE_ABSTRACT_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_LIST, GeeAbstractListClass))

typedef struct _GeeAbstractList GeeAbstractList;
typedef struct _GeeAbstractListClass GeeAbstractListClass;

#define GEE_TYPE_ABSTRACT_BIDIR_LIST (gee_abstract_bidir_list_get_type ())
#define GEE_ABSTRACT_BIDIR_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirList))
#define GEE_ABSTRACT_BIDIR_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirListClass))
#define GEE_IS_ABSTRACT_BIDIR_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST))
#define GEE_IS_ABSTRACT_BIDIR_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_BIDIR_LIST))
#define GEE_ABSTRACT_BIDIR_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_BIDIR_LIST, GeeAbstractBidirListClass))

typedef struct _GeeAbstractBidirList GeeAbstractBidirList;
typedef struct _GeeAbstractBidirListClass GeeAbstractBidirListClass;

#define GEE_TYPE_ARRAY_LIST (gee_array_list_get_type ())
#define GEE_ARRAY_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ARRAY_LIST, GeeArrayList))
#define GEE_ARRAY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ARRAY_LIST, GeeArrayListClass))
#define GEE_IS_ARRAY_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ARRAY_LIST))
#define GEE_IS_ARRAY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ARRAY_LIST))
#define GEE_ARRAY_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ARRAY_LIST, GeeArrayListClass))

typedef struct _GeeArrayList GeeArrayList;
typedef struct _GeeArrayListClass GeeArrayListClass;
typedef struct _GeeHazardPointerFreeNode GeeHazardPointerFreeNode;

#define GEE_TYPE_TRAVERSABLE (gee_traversable_get_type ())
#define GEE_TRAVERSABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_TRAVERSABLE, GeeTraversable))
#define GEE_IS_TRAVERSABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_TRAVERSABLE))
#define GEE_TRAVERSABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_TRAVERSABLE, GeeTraversableIface))

typedef struct _GeeTraversable GeeTraversable;
typedef struct _GeeTraversableIface GeeTraversableIface;

#define GEE_TRAVERSABLE_TYPE_STREAM (gee_traversable_stream_get_type ())

#define GEE_TYPE_LAZY (gee_lazy_get_type ())
#define GEE_LAZY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_LAZY, GeeLazy))
#define GEE_LAZY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_LAZY, GeeLazyClass))
#define GEE_IS_LAZY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_LAZY))
#define GEE_IS_LAZY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_LAZY))
#define GEE_LAZY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_LAZY, GeeLazyClass))

typedef struct _GeeLazy GeeLazy;
typedef struct _GeeLazyClass GeeLazyClass;

#define GEE_TYPE_ITERATOR (gee_iterator_get_type ())
#define GEE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ITERATOR, GeeIterator))
#define GEE_IS_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ITERATOR))
#define GEE_ITERATOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_ITERATOR, GeeIteratorIface))

typedef struct _GeeIterator GeeIterator;
typedef struct _GeeIteratorIface GeeIteratorIface;

#define GEE_TYPE_ITERABLE (gee_iterable_get_type ())
#define GEE_ITERABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ITERABLE, GeeIterable))
#define GEE_IS_ITERABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ITERABLE))
#define GEE_ITERABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_ITERABLE, GeeIterableIface))

typedef struct _GeeIterable GeeIterable;
typedef struct _GeeIterableIface GeeIterableIface;

#define GEE_TYPE_COLLECTION (gee_collection_get_type ())
#define GEE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_COLLECTION, GeeCollection))
#define GEE_IS_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_COLLECTION))
#define GEE_COLLECTION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_COLLECTION, GeeCollectionIface))

typedef struct _GeeCollection GeeCollection;
typedef struct _GeeCollectionIface GeeCollectionIface;

#define GEE_TYPE_QUEUE (gee_queue_get_type ())
#define GEE_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_QUEUE, GeeQueue))
#define GEE_IS_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_QUEUE))
#define GEE_QUEUE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GEE_TYPE_QUEUE, GeeQueueIface))

typedef struct _GeeQueue GeeQueue;
typedef struct _GeeQueueIface GeeQueueIface;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define GEE_HAZARD_POINTER_TYPE_RELEASE_POLICY (gee_hazard_pointer_release_policy_get_type ())
typedef struct _GeeHazardPointerContext GeeHazardPointerContext;
#define _gee_hazard_pointer_context_free0(var) ((var == NULL) ? NULL : (var = (gee_hazard_pointer_context_free (var), NULL)))
#define _g_thread_unref0(var) ((var == NULL) ? NULL : (var = (g_thread_unref (var), NULL)))
#define _t_destroy_func0(var) (((var == NULL) || (t_destroy_func == NULL)) ? NULL : (var = (t_destroy_func (var), NULL)))

#define GEE_TYPE_LINKED_LIST (gee_linked_list_get_type ())
#define GEE_LINKED_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_LINKED_LIST, GeeLinkedList))
#define GEE_LINKED_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_LINKED_LIST, GeeLinkedListClass))
#define GEE_IS_LINKED_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_LINKED_LIST))
#define GEE_IS_LINKED_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_LINKED_LIST))
#define GEE_LINKED_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_LINKED_LIST, GeeLinkedListClass))

typedef struct _GeeLinkedList GeeLinkedList;
typedef struct _GeeLinkedListClass GeeLinkedListClass;
typedef struct _Block10Data Block10Data;
#define _g_destroy_func0(var) (((var == NULL) || (g_destroy_func == NULL)) ? NULL : (var = (g_destroy_func (var), NULL)))
#define _gee_hazard_pointer_free0(var) ((var == NULL) ? NULL : (var = (gee_hazard_pointer_free (var), NULL)))

#define GEE_TYPE_ABSTRACT_SET (gee_abstract_set_get_type ())
#define GEE_ABSTRACT_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_ABSTRACT_SET, GeeAbstractSet))
#define GEE_ABSTRACT_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_ABSTRACT_SET, GeeAbstractSetClass))
#define GEE_IS_ABSTRACT_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_ABSTRACT_SET))
#define GEE_IS_ABSTRACT_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_ABSTRACT_SET))
#define GEE_ABSTRACT_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_ABSTRACT_SET, GeeAbstractSetClass))

typedef struct _GeeAbstractSet GeeAbstractSet;
typedef struct _GeeAbstractSetClass GeeAbstractSetClass;

#define GEE_TYPE_HASH_SET (gee_hash_set_get_type ())
#define GEE_HASH_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_HASH_SET, GeeHashSet))
#define GEE_HASH_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_HASH_SET, GeeHashSetClass))
#define GEE_IS_HASH_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_HASH_SET))
#define GEE_IS_HASH_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_HASH_SET))
#define GEE_HASH_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_HASH_SET, GeeHashSetClass))

typedef struct _GeeHashSet GeeHashSet;
typedef struct _GeeHashSetClass GeeHashSetClass;
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#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; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _GeeHazardPointer {
	GeeHazardPointerNode* _node;
};

typedef enum  {
	GEE_HAZARD_POINTER_POLICY_DEFAULT,
	GEE_HAZARD_POINTER_POLICY_THREAD_EXIT,
	GEE_HAZARD_POINTER_POLICY_TRY_FREE,
	GEE_HAZARD_POINTER_POLICY_FREE,
	GEE_HAZARD_POINTER_POLICY_TRY_RELEASE,
	GEE_HAZARD_POINTER_POLICY_RELEASE
} GeeHazardPointerPolicy;

typedef gboolean (*GeeForallFunc) (gpointer g, void* user_data);
typedef enum  {
	GEE_TRAVERSABLE_STREAM_YIELD,
	GEE_TRAVERSABLE_STREAM_CONTINUE,
	GEE_TRAVERSABLE_STREAM_END,
	GEE_TRAVERSABLE_STREAM_WAIT
} GeeTraversableStream;

typedef GeeTraversableStream (*GeeStreamFunc) (GeeTraversableStream state, GeeLazy* g, GeeLazy** lazy, void* user_data);
struct _GeeIteratorIface {
	GTypeInterface parent_iface;
	gboolean (*next) (GeeIterator* self);
	gboolean (*has_next) (GeeIterator* self);
	gpointer (*get) (GeeIterator* self);
	void (*remove) (GeeIterator* self);
	gboolean (*get_valid) (GeeIterator* self);
	gboolean (*get_read_only) (GeeIterator* self);
};

typedef gpointer (*GeeFoldFunc) (gpointer g, gpointer a, void* user_data);
typedef gpointer (*GeeMapFunc) (gpointer g, void* user_data);
typedef gboolean (*GeePredicate) (gconstpointer g, void* user_data);
typedef GeeIterator* (*GeeFlatMapFunc) (gpointer g, void* user_data);
struct _GeeTraversableIface {
	GTypeInterface parent_iface;
	GType (*get_g_type) (GeeTraversable* self);
	GBoxedCopyFunc (*get_g_dup_func) (GeeTraversable* self);
	GDestroyNotify (*get_g_destroy_func) (GeeTraversable* self);
	gboolean (*foreach) (GeeTraversable* self, GeeForallFunc f, void* f_target);
	GeeIterator* (*stream) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeStreamFunc f, void* f_target, GDestroyNotify f_target_destroy_notify);
	gpointer (*fold) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldFunc f, void* f_target, gpointer seed);
	GeeIterator* (*map) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeMapFunc f, void* f_target);
	GeeIterator* (*scan) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldFunc f, void* f_target, gpointer seed);
	GeeIterator* (*filter) (GeeTraversable* self, GeePredicate pred, void* pred_target, GDestroyNotify pred_target_destroy_notify);
	GeeIterator* (*chop) (GeeTraversable* self, gint offset, gint length);
	GType (*get_element_type) (GeeTraversable* self);
	GeeIterator* (*flat_map) (GeeTraversable* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFlatMapFunc f, void* f_target, GDestroyNotify f_target_destroy_notify);
	GeeIterator** (*tee) (GeeTraversable* self, guint forks, int* result_length1);
};

struct _GeeIterableIface {
	GTypeInterface parent_iface;
	GType (*get_g_type) (GeeIterable* self);
	GBoxedCopyFunc (*get_g_dup_func) (GeeIterable* self);
	GDestroyNotify (*get_g_destroy_func) (GeeIterable* self);
	GeeIterator* (*iterator) (GeeIterable* self);
};

struct _GeeCollectionIface {
	GTypeInterface parent_iface;
	GType (*get_g_type) (GeeCollection* self);
	GBoxedCopyFunc (*get_g_dup_func) (GeeCollection* self);
	GDestroyNotify (*get_g_destroy_func) (GeeCollection* self);
	gboolean (*contains) (GeeCollection* self, gconstpointer item);
	gboolean (*add) (GeeCollection* self, gconstpointer item);
	gboolean (*remove) (GeeCollection* self, gconstpointer item);
	void (*clear) (GeeCollection* self);
	gboolean (*add_all) (GeeCollection* self, GeeCollection* collection);
	gboolean (*contains_all) (GeeCollection* self, GeeCollection* collection);
	gboolean (*remove_all) (GeeCollection* self, GeeCollection* collection);
	gboolean (*retain_all) (GeeCollection* self, GeeCollection* collection);
	gpointer* (*to_array) (GeeCollection* self, int* result_length1);
	gint (*get_size) (GeeCollection* self);
	gboolean (*get_is_empty) (GeeCollection* self);
	gboolean (*get_read_only) (GeeCollection* self);
	GeeCollection* (*get_read_only_view) (GeeCollection* self);
	gboolean (*add_all_array) (GeeCollection* self, gpointer* array, int array_length1);
	gboolean (*contains_all_array) (GeeCollection* self, gpointer* array, int array_length1);
	gboolean (*remove_all_array) (GeeCollection* self, gpointer* array, int array_length1);
	gboolean (*add_all_iterator) (GeeCollection* self, GeeIterator* iter);
	gboolean (*contains_all_iterator) (GeeCollection* self, GeeIterator* iter);
	gboolean (*remove_all_iterator) (GeeCollection* self, GeeIterator* iter);
};

struct _GeeQueueIface {
	GTypeInterface parent_iface;
	GType (*get_g_type) (GeeQueue* self);
	GBoxedCopyFunc (*get_g_dup_func) (GeeQueue* self);
	GDestroyNotify (*get_g_destroy_func) (GeeQueue* self);
	gboolean (*offer) (GeeQueue* self, gconstpointer element);
	gpointer (*peek) (GeeQueue* self);
	gpointer (*poll) (GeeQueue* self);
	gint (*drain) (GeeQueue* self, GeeCollection* recipient, gint amount);
	gint (*get_capacity) (GeeQueue* self);
	gint (*get_remaining_capacity) (GeeQueue* self);
	gboolean (*get_is_full) (GeeQueue* self);
};

typedef enum  {
	GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD,
	GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP
} GeeHazardPointerReleasePolicy;

struct _GeeHazardPointerContext {
	GeeHazardPointerContext* _parent;
	GeeArrayList* _to_free;
	GeeHazardPointerPolicy* _policy;
};

typedef gboolean (*GeeEqualDataFunc) (gconstpointer a, gconstpointer b, void* user_data);
struct _Block10Data {
	int _ref_count_;
	GeeCollection* to_free;
};

typedef guint (*GeeHashDataFunc) (gconstpointer v, void* user_data);
struct _GeeHazardPointerFreeNode {
	void* pointer;
	GDestroyNotify destroy_notify;
};

struct _GeeHazardPointerNode {
	GeeHazardPointerNode* _next;
	gint _active;
	void* _hazard;
};


extern gint gee_hazard_pointer__default_policy;
extern gint gee_hazard_pointer__thread_exit_policy;
extern GStaticMutex gee_hazard_pointer__queue_mutex;
extern GeeQueue* gee_hazard_pointer__queue;
extern GeeArrayList* gee_hazard_pointer__global_to_free;
extern gint gee_hazard_pointer_release_policy;
extern GeeHazardPointerNode* gee_hazard_pointer__head;
GeeHazardPointerNode* gee_hazard_pointer__head = NULL;
gint gee_hazard_pointer__default_policy = (gint) GEE_HAZARD_POINTER_POLICY_TRY_FREE;
gint gee_hazard_pointer__thread_exit_policy = (gint) GEE_HAZARD_POINTER_POLICY_RELEASE;
gint gee_hazard_pointer_release_policy = 0;
GeeQueue* gee_hazard_pointer__queue = NULL;
GStaticMutex gee_hazard_pointer__queue_mutex = G_STATIC_MUTEX_INIT;
GeeArrayList* gee_hazard_pointer__global_to_free = NULL;
static guint gee_hazard_pointer_context_THRESHOLD;
extern GStaticPrivate gee_hazard_pointer_context__current_context;
GStaticPrivate gee_hazard_pointer_context__current_context = G_STATIC_PRIVATE_INIT;
extern GStaticPrivate gee_hazard_pointer_context__root_context;
GStaticPrivate gee_hazard_pointer_context__root_context = G_STATIC_PRIVATE_INIT;
static guint gee_hazard_pointer_context_THRESHOLD = (guint) 10;

void gee_hazard_pointer_free (GeeHazardPointer* self);
G_GNUC_INTERNAL void gee_hazard_pointer_node_free (GeeHazardPointerNode* self);
static void gee_hazard_pointer_instance_init (GeeHazardPointer * self);
G_GNUC_INTERNAL void gee_hazard_pointer_node_release (GeeHazardPointerNode* self);
GType gee_hazard_pointer_policy_get_type (void) G_GNUC_CONST;
gboolean gee_hazard_pointer_policy_is_concrete (GeeHazardPointerPolicy self);
gboolean gee_hazard_pointer_policy_is_blocking (GeeHazardPointerPolicy self);
gboolean gee_hazard_pointer_policy_is_safe (GeeHazardPointerPolicy self);
GeeHazardPointerPolicy gee_hazard_pointer_policy_to_concrete (GeeHazardPointerPolicy self);
GType gee_abstract_collection_get_type (void) G_GNUC_CONST;
GType gee_abstract_list_get_type (void) G_GNUC_CONST;
GType gee_abstract_bidir_list_get_type (void) G_GNUC_CONST;
GType gee_array_list_get_type (void) G_GNUC_CONST;
G_GNUC_INTERNAL void gee_hazard_pointer_free_node_free (GeeHazardPointerFreeNode* self);
G_GNUC_INTERNAL gboolean gee_hazard_pointer_policy_perform (GeeHazardPointerPolicy self, GeeArrayList** to_free);
G_GNUC_INTERNAL gboolean gee_hazard_pointer_try_free (GeeArrayList* to_free);
G_GNUC_INTERNAL void gee_hazard_pointer_release_policy_ensure_start (void);
GType gee_traversable_stream_get_type (void) G_GNUC_CONST;
gpointer gee_lazy_ref (gpointer instance);
void gee_lazy_unref (gpointer instance);
GParamSpec* gee_param_spec_lazy (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void gee_value_set_lazy (GValue* value, gpointer v_object);
void gee_value_take_lazy (GValue* value, gpointer v_object);
gpointer gee_value_get_lazy (const GValue* value);
GType gee_lazy_get_type (void) G_GNUC_CONST;
GType gee_iterator_get_type (void) G_GNUC_CONST;
GType gee_traversable_get_type (void) G_GNUC_CONST;
GType gee_iterable_get_type (void) G_GNUC_CONST;
GType gee_collection_get_type (void) G_GNUC_CONST;
GType gee_queue_get_type (void) G_GNUC_CONST;
gboolean gee_queue_offer (GeeQueue* self, gconstpointer element);
GType gee_hazard_pointer_release_policy_get_type (void) G_GNUC_CONST;
static void gee_hazard_pointer_release_policy_start (GeeHazardPointerReleasePolicy _self_);
static gboolean ___lambda49_ (void);
void gee_hazard_pointer_context_free (GeeHazardPointerContext* self);
GeeHazardPointerContext* gee_hazard_pointer_context_new (GeeHazardPointerPolicy* policy);
GeeHazardPointerContext* gee_hazard_pointer_context_new (GeeHazardPointerPolicy* policy);
static inline void gee_hazard_pointer_release_policy_pull_from_queue (GeeCollection* to_free, gboolean do_lock);
gboolean gee_collection_get_is_empty (GeeCollection* self);
void gee_hazard_pointer_context_try_free (GeeHazardPointerContext* self);
static gpointer ____lambda49__gthread_func (gpointer self);
GeeArrayList* gee_array_list_new (GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
GeeArrayList* gee_array_list_construct (GType object_type, GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
static gboolean ___lambda51_ (void);
static void gee_hazard_pointer_release_policy_swap (GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, gpointer* a, gpointer* b);
static gboolean ____lambda51__gsource_func (gpointer self);
GeeLinkedList* gee_linked_list_new (GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
GeeLinkedList* gee_linked_list_construct (GType object_type, GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
GType gee_linked_list_get_type (void) G_GNUC_CONST;
static Block10Data* block10_data_ref (Block10Data* _data10_);
static void block10_data_unref (void * _userdata_);
gint gee_queue_drain (GeeQueue* self, GeeCollection* recipient, gint amount);
gboolean gee_traversable_foreach (GeeTraversable* self, GeeForallFunc f, void* f_target);
static gboolean ___lambda50_ (Block10Data* _data10_, GeeArrayList* x);
gboolean gee_collection_add_all (GeeCollection* self, GeeCollection* collection);
static gboolean ____lambda50__gee_forall_func (gpointer g, gpointer self);
GeeHazardPointer* gee_hazard_pointer_new (gconstpointer* ptr);
GeeHazardPointer* gee_hazard_pointer_new (gconstpointer* ptr);
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_acquire (void);
G_GNUC_INTERNAL void gee_hazard_pointer_node_set (GeeHazardPointerNode* self, void* ptr);
G_GNUC_INTERNAL GeeHazardPointer* gee_hazard_pointer_new_from_node (GeeHazardPointerNode* node);
G_GNUC_INTERNAL GeeHazardPointer* gee_hazard_pointer_new_from_node (GeeHazardPointerNode* node);
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);
gpointer gee_hazard_pointer_get_pointer (GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, gconstpointer** aptr, gsize mask, gsize* mask_out);
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);
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);
void gee_hazard_pointer_release (GeeHazardPointer* self, GDestroyNotify notify);
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);
gconstpointer gee_hazard_pointer_get (GeeHazardPointer* self, gboolean other_thread);
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);
G_GNUC_INTERNAL GeeHazardPointerContext* gee_hazard_pointer_context_get_current_context (void);
G_GNUC_INTERNAL void gee_hazard_pointer_context_release_ptr (GeeHazardPointerContext* self, void* ptr, GDestroyNotify notify);
G_GNUC_INTERNAL void* gee_hazard_pointer_node_get (GeeHazardPointerNode* self, gboolean safe);
void gee_hazard_pointer_set_default_policy (GeeHazardPointerPolicy policy);
void gee_hazard_pointer_set_thread_exit_policy (GeeHazardPointerPolicy policy);
gboolean gee_hazard_pointer_set_release_policy (GeeHazardPointerReleasePolicy policy);
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_get_head (void);
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_get_next (GeeHazardPointerNode* self);
G_GNUC_INTERNAL gboolean gee_hazard_pointer_node_activate (GeeHazardPointerNode* self);
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_new (void);
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_new (void);
G_GNUC_INTERNAL void gee_hazard_pointer_node_set_next (GeeHazardPointerNode* self, GeeHazardPointerNode* next);
GeeHashSet* gee_hash_set_new (GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeHashDataFunc hash_func, void* hash_func_target, GDestroyNotify hash_func_target_destroy_notify, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
GeeHashSet* gee_hash_set_construct (GType object_type, GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, GeeHashDataFunc hash_func, void* hash_func_target, GDestroyNotify hash_func_target_destroy_notify, GeeEqualDataFunc equal_func, void* equal_func_target, GDestroyNotify equal_func_target_destroy_notify);
GType gee_abstract_set_get_type (void) G_GNUC_CONST;
GType gee_hash_set_get_type (void) G_GNUC_CONST;
gboolean gee_collection_add (GeeCollection* self, gconstpointer item);
gint gee_abstract_collection_get_size (GeeAbstractCollection* self);
gpointer gee_abstract_list_get (GeeAbstractList* self, gint index);
gboolean gee_collection_contains (GeeCollection* self, gconstpointer item);
gpointer gee_abstract_list_remove_at (GeeAbstractList* self, gint index);
void gee_abstract_list_set (GeeAbstractList* self, gint index, gconstpointer item);
static void gee_hazard_pointer_context_instance_init (GeeHazardPointerContext * self);
gboolean gee_array_list_add_all (GeeArrayList* self, GeeCollection* collection);
static GeeHazardPointerPolicy* _gee_hazard_pointer_policy_dup (GeeHazardPointerPolicy* self);
void gee_hazard_pointer_context_free_all (GeeHazardPointerContext* self);
void gee_hazard_pointer_context_try_release (GeeHazardPointerContext* self);
void gee_hazard_pointer_context_release (GeeHazardPointerContext* self);
G_GNUC_INTERNAL GeeHazardPointerFreeNode* gee_hazard_pointer_free_node_new (void);
G_GNUC_INTERNAL GeeHazardPointerFreeNode* gee_hazard_pointer_free_node_new (void);
gboolean gee_abstract_collection_add (GeeAbstractCollection* self, gconstpointer item);
static void gee_hazard_pointer_free_node_instance_init (GeeHazardPointerFreeNode * self);
static void gee_hazard_pointer_node_instance_init (GeeHazardPointerNode * self);
G_GNUC_INTERNAL gboolean gee_hazard_pointer_node_is_active (GeeHazardPointerNode* self);


/**
 * Checks if the policy is concrete or if it depends on global variables.
 *
 * @return ``true`` if this policy does not depend on global variables
 */
gboolean gee_hazard_pointer_policy_is_concrete (GeeHazardPointerPolicy self) {
	gboolean result = FALSE;
	switch (self) {
		case GEE_HAZARD_POINTER_POLICY_DEFAULT:
		case GEE_HAZARD_POINTER_POLICY_THREAD_EXIT:
		{
			result = FALSE;
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
		case GEE_HAZARD_POINTER_POLICY_FREE:
		case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
		case GEE_HAZARD_POINTER_POLICY_RELEASE:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}


/**
 * Checks if policy blocks or is lock-free.
 * Please note that it works on a concrete policy only.
 *
 * @return ``true`` if the policy may block the thread.
 */
gboolean gee_hazard_pointer_policy_is_blocking (GeeHazardPointerPolicy self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	_tmp0_ = gee_hazard_pointer_policy_is_concrete (self);
	_vala_return_val_if_fail (_tmp0_, "this.is_concrete ()", FALSE);
	switch (self) {
		case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
		case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
		{
			result = FALSE;
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_FREE:
		case GEE_HAZARD_POINTER_POLICY_RELEASE:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}


/**
 * Checks if policy guarantees freeing all elements.
 * Please note that it works on a concrete policy only.
 *
 * @return ``true`` if the policy guarantees freeing all elements.
 */
gboolean gee_hazard_pointer_policy_is_safe (GeeHazardPointerPolicy self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	_tmp0_ = gee_hazard_pointer_policy_is_concrete (self);
	_vala_return_val_if_fail (_tmp0_, "this.is_concrete ()", FALSE);
	switch (self) {
		case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
		case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
		{
			result = FALSE;
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_FREE:
		case GEE_HAZARD_POINTER_POLICY_RELEASE:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}


/**
 * Finds concrete policy which corresponds to given policy.
 *
 * @return Policy that corresponds to given policy at given time in given thread.
 */
GeeHazardPointerPolicy gee_hazard_pointer_policy_to_concrete (GeeHazardPointerPolicy self) {
	GeeHazardPointerPolicy result = 0;
	GeeHazardPointerPolicy _tmp8_ = 0;
	gboolean _tmp9_ = FALSE;
	switch (self) {
		case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
		case GEE_HAZARD_POINTER_POLICY_FREE:
		case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
		case GEE_HAZARD_POINTER_POLICY_RELEASE:
		{
			GeeHazardPointerPolicy _tmp0_ = 0;
			gboolean _tmp1_ = FALSE;
			result = self;
			_tmp0_ = result;
			_tmp1_ = gee_hazard_pointer_policy_is_concrete (_tmp0_);
			_vala_warn_if_fail (_tmp1_, "result.is_concrete ()");
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_DEFAULT:
		{
			gint _tmp2_ = 0;
			GeeHazardPointerPolicy _tmp3_ = 0;
			gboolean _tmp4_ = FALSE;
			_tmp2_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__default_policy));
			result = (GeeHazardPointerPolicy) _tmp2_;
			_tmp3_ = result;
			_tmp4_ = gee_hazard_pointer_policy_is_concrete (_tmp3_);
			_vala_warn_if_fail (_tmp4_, "result.is_concrete ()");
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_THREAD_EXIT:
		{
			gint _tmp5_ = 0;
			GeeHazardPointerPolicy _tmp6_ = 0;
			gboolean _tmp7_ = FALSE;
			_tmp5_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy));
			result = (GeeHazardPointerPolicy) _tmp5_;
			_tmp6_ = result;
			_tmp7_ = gee_hazard_pointer_policy_is_concrete (_tmp6_);
			_vala_warn_if_fail (_tmp7_, "result.is_concrete ()");
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
	_tmp8_ = result;
	_tmp9_ = gee_hazard_pointer_policy_is_concrete (_tmp8_);
	_vala_warn_if_fail (_tmp9_, "result.is_concrete ()");
}


/**
 * Runs the policy.
 * @param to_free List containing elements to free.
 * @return Non-empty list of not freed elements or ``null`` if all elements have been disposed.
 */
G_GNUC_INTERNAL gboolean gee_hazard_pointer_policy_perform (GeeHazardPointerPolicy self, GeeArrayList** to_free) {
	gboolean result = FALSE;
	GeeHazardPointerPolicy _tmp0_ = 0;
	g_return_val_if_fail (*to_free != NULL, FALSE);
	_tmp0_ = gee_hazard_pointer_policy_to_concrete (self);
	switch (_tmp0_) {
		case GEE_HAZARD_POINTER_POLICY_TRY_FREE:
		{
			GeeArrayList* _tmp1_ = NULL;
			gboolean _tmp2_ = FALSE;
			_tmp1_ = *to_free;
			_tmp2_ = gee_hazard_pointer_try_free (_tmp1_);
			result = _tmp2_;
			return result;
		}
		case GEE_HAZARD_POINTER_POLICY_FREE:
		{
			while (TRUE) {
				GeeArrayList* _tmp3_ = NULL;
				gboolean _tmp4_ = FALSE;
				_tmp3_ = *to_free;
				_tmp4_ = gee_hazard_pointer_try_free (_tmp3_);
				if (!_tmp4_) {
					break;
				}
				g_thread_yield ();
			}
			break;
		}
		case GEE_HAZARD_POINTER_POLICY_TRY_RELEASE:
		{
			gboolean _tmp5_ = FALSE;
			gee_hazard_pointer_release_policy_ensure_start ();
			_tmp5_ = g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex);
			if (_tmp5_) {
				GeeQueue* _tmp6_ = NULL;
				GeeArrayList* _tmp7_ = NULL;
				GeeArrayList* _tmp8_ = NULL;
				_tmp6_ = gee_hazard_pointer__queue;
				_tmp7_ = *to_free;
				*to_free = NULL;
				_tmp8_ = _tmp7_;
				gee_queue_offer (_tmp6_, _tmp8_);
				_g_object_unref0 (_tmp8_);
				g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
				result = TRUE;
				return result;
			} else {
				result = FALSE;
				return result;
			}
		}
		case GEE_HAZARD_POINTER_POLICY_RELEASE:
		{
			GeeQueue* _tmp9_ = NULL;
			GeeArrayList* _tmp10_ = NULL;
			GeeArrayList* _tmp11_ = NULL;
			gee_hazard_pointer_release_policy_ensure_start ();
			g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
			_tmp9_ = gee_hazard_pointer__queue;
			_tmp10_ = *to_free;
			*to_free = NULL;
			_tmp11_ = _tmp10_;
			gee_queue_offer (_tmp9_, _tmp11_);
			_g_object_unref0 (_tmp11_);
			g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
			result = TRUE;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
	result = FALSE;
	return result;
}


/**
 * Policy determines what happens on exit from Context.
 */
GType gee_hazard_pointer_policy_get_type (void) {
	static volatile gsize gee_hazard_pointer_policy_type_id__volatile = 0;
	if (g_once_init_enter (&gee_hazard_pointer_policy_type_id__volatile)) {
		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}};
		GType gee_hazard_pointer_policy_type_id;
		gee_hazard_pointer_policy_type_id = g_enum_register_static ("GeeHazardPointerPolicy", values);
		g_once_init_leave (&gee_hazard_pointer_policy_type_id__volatile, gee_hazard_pointer_policy_type_id);
	}
	return gee_hazard_pointer_policy_type_id__volatile;
}


static gboolean ___lambda49_ (void) {
	gboolean result = FALSE;
	GeeHazardPointerContext* ctx = NULL;
	GeeHazardPointerPolicy _tmp0_ = 0;
	GeeHazardPointerContext* _tmp1_ = NULL;
	_tmp0_ = GEE_HAZARD_POINTER_POLICY_TRY_FREE;
	_tmp1_ = gee_hazard_pointer_context_new (&_tmp0_);
	ctx = _tmp1_;
	while (TRUE) {
		GeeHazardPointerContext* _tmp2_ = NULL;
		GeeArrayList* _tmp3_ = NULL;
		GeeHazardPointerContext* _tmp4_ = NULL;
		GeeArrayList* _tmp5_ = NULL;
		gboolean _tmp6_ = FALSE;
		gboolean _tmp7_ = FALSE;
		GeeHazardPointerContext* _tmp8_ = NULL;
		GeeHazardPointerContext* _tmp9_ = NULL;
		GeeArrayList* _tmp10_ = NULL;
		gboolean _tmp11_ = FALSE;
		gboolean _tmp12_ = FALSE;
		g_thread_yield ();
		_tmp2_ = ctx;
		_tmp3_ = _tmp2_->_to_free;
		_tmp4_ = ctx;
		_tmp5_ = _tmp4_->_to_free;
		_tmp6_ = gee_collection_get_is_empty ((GeeCollection*) _tmp5_);
		_tmp7_ = _tmp6_;
		gee_hazard_pointer_release_policy_pull_from_queue ((GeeCollection*) _tmp3_, _tmp7_);
		_tmp8_ = ctx;
		gee_hazard_pointer_context_try_free (_tmp8_);
		_tmp9_ = ctx;
		_tmp10_ = _tmp9_->_to_free;
		_tmp11_ = gee_collection_get_is_empty ((GeeCollection*) _tmp10_);
		_tmp12_ = _tmp11_;
		if (_tmp12_) {
			g_usleep ((gulong) 100000);
		}
	}
	_gee_hazard_pointer_context_free0 (ctx);
	return result;
}


static gpointer ____lambda49__gthread_func (gpointer self) {
	gpointer result;
	result = (gpointer) ((gintptr) ___lambda49_ ());
	return result;
}


static gboolean ___lambda51_ (void) {
	gboolean result = FALSE;
	GeeHazardPointerContext* ctx = NULL;
	GeeHazardPointerPolicy _tmp0_ = 0;
	GeeHazardPointerContext* _tmp1_ = NULL;
	GeeArrayList* _tmp2_ = NULL;
	_tmp0_ = GEE_HAZARD_POINTER_POLICY_TRY_FREE;
	_tmp1_ = gee_hazard_pointer_context_new (&_tmp0_);
	ctx = _tmp1_;
	gee_hazard_pointer_release_policy_swap (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, g_object_unref, &gee_hazard_pointer__global_to_free, &ctx->_to_free);
	_tmp2_ = ctx->_to_free;
	gee_hazard_pointer_release_policy_pull_from_queue ((GeeCollection*) _tmp2_, FALSE);
	gee_hazard_pointer_context_try_free (ctx);
	gee_hazard_pointer_release_policy_swap (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, g_object_unref, &gee_hazard_pointer__global_to_free, &ctx->_to_free);
	result = TRUE;
	_gee_hazard_pointer_context_free0 (ctx);
	return result;
}


static gboolean ____lambda51__gsource_func (gpointer self) {
	gboolean result;
	result = ___lambda51_ ();
	return result;
}


static void gee_hazard_pointer_release_policy_start (GeeHazardPointerReleasePolicy _self_) {
	GeeHazardPointerReleasePolicy _tmp0_ = 0;
	_tmp0_ = _self_;
	switch (_tmp0_) {
		case GEE_HAZARD_POINTER_RELEASE_POLICY_HELPER_THREAD:
		{
			GThread* _tmp1_ = NULL;
			GThread* _tmp2_ = NULL;
			_tmp1_ = g_thread_new ("<<libgee hazard pointer>>", ____lambda49__gthread_func, NULL);
			_tmp2_ = _tmp1_;
			_g_thread_unref0 (_tmp2_);
			break;
		}
		case GEE_HAZARD_POINTER_RELEASE_POLICY_MAIN_LOOP:
		{
			GeeArrayList* _tmp3_ = NULL;
			_tmp3_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
			_g_object_unref0 (gee_hazard_pointer__global_to_free);
			gee_hazard_pointer__global_to_free = _tmp3_;
			g_idle_add_full (G_PRIORITY_LOW, ____lambda51__gsource_func, NULL, NULL);
			break;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}


static void gee_hazard_pointer_release_policy_swap (GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, gpointer* a, gpointer* b) {
	gpointer tmp = NULL;
	gpointer _tmp0_ = NULL;
	gpointer _tmp1_ = NULL;
	gpointer _tmp2_ = NULL;
	_tmp0_ = *a;
	*a = NULL;
	tmp = _tmp0_;
	_tmp1_ = *b;
	*b = NULL;
	_t_destroy_func0 (*a);
	*a = _tmp1_;
	_tmp2_ = tmp;
	tmp = NULL;
	_t_destroy_func0 (*b);
	*b = _tmp2_;
	_t_destroy_func0 (tmp);
}


/**
 * Ensures that helper methods are started.
 */
G_GNUC_INTERNAL inline void gee_hazard_pointer_release_policy_ensure_start (void) {
	gint policy = 0;
	gint _tmp0_ = 0;
	gint _tmp1_ = 0;
	gboolean _tmp2_ = FALSE;
	_tmp0_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
	policy = _tmp0_;
	_tmp1_ = policy;
	if ((_tmp1_ & (1 << ((sizeof (gint) * 8) - 1))) != 0) {
		return;
	}
	_tmp2_ = g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex);
	if (_tmp2_) {
		gint _tmp3_ = 0;
		gint _tmp4_ = 0;
		_tmp3_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
		policy = _tmp3_;
		_tmp4_ = policy;
		if ((_tmp4_ & (1 << ((sizeof (gint) * 8) - 1))) == 0) {
			GeeLinkedList* _tmp5_ = NULL;
			gint _tmp6_ = 0;
			gint _tmp7_ = 0;
			_tmp5_ = gee_linked_list_new (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
			_g_object_unref0 (gee_hazard_pointer__queue);
			gee_hazard_pointer__queue = (GeeQueue*) _tmp5_;
			_tmp6_ = g_atomic_int_add ((volatile gint *) (&gee_hazard_pointer_release_policy), (gint) (1 << ((sizeof (gint) * 8) - 1)));
			policy = _tmp6_;
			_tmp7_ = policy;
			gee_hazard_pointer_release_policy_start ((GeeHazardPointerReleasePolicy) _tmp7_);
		}
		g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
	}
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static Block10Data* block10_data_ref (Block10Data* _data10_) {
	g_atomic_int_inc (&_data10_->_ref_count_);
	return _data10_;
}


static void block10_data_unref (void * _userdata_) {
	Block10Data* _data10_;
	_data10_ = (Block10Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data10_->_ref_count_)) {
		_g_object_unref0 (_data10_->to_free);
		g_slice_free (Block10Data, _data10_);
	}
}


static gboolean ___lambda50_ (Block10Data* _data10_, GeeArrayList* x) {
	gboolean result = FALSE;
	GeeCollection* _tmp0_ = NULL;
	GeeArrayList* _tmp1_ = NULL;
	g_return_val_if_fail (x != NULL, FALSE);
	_tmp0_ = _data10_->to_free;
	_tmp1_ = x;
	gee_collection_add_all (_tmp0_, (GeeCollection*) _tmp1_);
	result = TRUE;
	_g_object_unref0 (x);
	return result;
}


static gboolean ____lambda50__gee_forall_func (gpointer g, gpointer self) {
	gboolean result;
	result = ___lambda50_ (self, (GeeArrayList*) g);
	return result;
}


static inline void gee_hazard_pointer_release_policy_pull_from_queue (GeeCollection* to_free, gboolean do_lock) {
	Block10Data* _data10_;
	GeeCollection* _tmp0_ = NULL;
	GeeCollection* _tmp1_ = NULL;
	gboolean locked = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp5_ = FALSE;
	g_return_if_fail (to_free != NULL);
	_data10_ = g_slice_new0 (Block10Data);
	_data10_->_ref_count_ = 1;
	_tmp0_ = to_free;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (_data10_->to_free);
	_data10_->to_free = _tmp1_;
	_tmp2_ = do_lock;
	locked = _tmp2_;
	_tmp3_ = do_lock;
	if (_tmp3_) {
		g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
	} else {
		gboolean _tmp4_ = FALSE;
		_tmp4_ = g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex);
		locked = _tmp4_;
	}
	_tmp5_ = locked;
	if (_tmp5_) {
		GeeCollection* temp = NULL;
		GeeArrayList* _tmp6_ = NULL;
		GeeQueue* _tmp7_ = NULL;
		GeeCollection* _tmp8_ = NULL;
		GeeCollection* _tmp9_ = NULL;
		_tmp6_ = gee_array_list_new (GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
		temp = (GeeCollection*) _tmp6_;
		_tmp7_ = gee_hazard_pointer__queue;
		_tmp8_ = temp;
		gee_queue_drain (_tmp7_, _tmp8_, -1);
		g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
		_tmp9_ = temp;
		gee_traversable_foreach ((GeeTraversable*) _tmp9_, ____lambda50__gee_forall_func, _data10_);
		_g_object_unref0 (temp);
	}
	block10_data_unref (_data10_);
	_data10_ = NULL;
}


/**
 * Release policy determines what happens with object freed by Policy.TRY_RELEASE
 * and Policy.RELEASE.
 */
GType gee_hazard_pointer_release_policy_get_type (void) {
	static volatile gsize gee_hazard_pointer_release_policy_type_id__volatile = 0;
	if (g_once_init_enter (&gee_hazard_pointer_release_policy_type_id__volatile)) {
		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}};
		GType gee_hazard_pointer_release_policy_type_id;
		gee_hazard_pointer_release_policy_type_id = g_enum_register_static ("GeeHazardPointerReleasePolicy", values);
		g_once_init_leave (&gee_hazard_pointer_release_policy_type_id__volatile, gee_hazard_pointer_release_policy_type_id);
	}
	return gee_hazard_pointer_release_policy_type_id__volatile;
}


/**
 * Creates a hazard pointer for a pointer.
 *
 * @param ptr Protected pointer
 */
GeeHazardPointer* gee_hazard_pointer_new (gconstpointer* ptr) {
	GeeHazardPointer* self;
	GeeHazardPointerNode* _tmp0_ = NULL;
	GeeHazardPointerNode* _tmp1_ = NULL;
	gconstpointer* _tmp2_ = NULL;
	self = g_slice_new0 (GeeHazardPointer);
	gee_hazard_pointer_instance_init (self);
	_tmp0_ = gee_hazard_pointer_acquire ();
	self->_node = _tmp0_;
	_tmp1_ = self->_node;
	_tmp2_ = ptr;
	gee_hazard_pointer_node_set (_tmp1_, (void*) _tmp2_);
	return self;
}


/**
 * Create a hazard pointer from Node.
 */
G_GNUC_INTERNAL GeeHazardPointer* gee_hazard_pointer_new_from_node (GeeHazardPointerNode* node) {
	GeeHazardPointer* self;
	GeeHazardPointerNode* _tmp0_ = NULL;
	g_return_val_if_fail (node != NULL, NULL);
	self = g_slice_new0 (GeeHazardPointer);
	gee_hazard_pointer_instance_init (self);
	_tmp0_ = node;
	self->_node = _tmp0_;
	return self;
}


/**
 * Gets hazard pointer from atomic pointer safely.
 *
 * @param aptr Atomic pointer.
 * @param mask Mask of bits.
 * @param mask_out Result of mask.
 * @return Hazard pointer containing the element.
 */
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) {
	gsize _vala_mask_out = 0UL;
	GeeHazardPointer* result = NULL;
	GeeHazardPointerNode* node = NULL;
	GeeHazardPointerNode* _tmp0_ = NULL;
	void* rptr = NULL;
	void* ptr = NULL;
	void* _tmp13_ = NULL;
	_tmp0_ = gee_hazard_pointer_acquire ();
	node = _tmp0_;
	rptr = NULL;
	ptr = NULL;
	_vala_mask_out = (gsize) 0;
	{
		gboolean _tmp1_ = FALSE;
		_tmp1_ = TRUE;
		while (TRUE) {
			gconstpointer** _tmp5_ = NULL;
			void* _tmp6_ = NULL;
			void* _tmp7_ = NULL;
			gsize _tmp8_ = 0UL;
			void* _tmp9_ = NULL;
			gsize _tmp10_ = 0UL;
			GeeHazardPointerNode* _tmp11_ = NULL;
			void* _tmp12_ = NULL;
			if (!_tmp1_) {
				void* _tmp2_ = NULL;
				gconstpointer** _tmp3_ = NULL;
				void* _tmp4_ = NULL;
				_tmp2_ = rptr;
				_tmp3_ = aptr;
				_tmp4_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) _tmp3_));
				if (!(_tmp2_ != _tmp4_)) {
					break;
				}
			}
			_tmp1_ = FALSE;
			_tmp5_ = aptr;
			_tmp6_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) _tmp5_));
			rptr = _tmp6_;
			_tmp7_ = rptr;
			_tmp8_ = mask;
			ptr = (void*) (((gsize) _tmp7_) & (~_tmp8_));
			_tmp9_ = rptr;
			_tmp10_ = mask;
			_vala_mask_out = ((gsize) _tmp9_) & _tmp10_;
			_tmp11_ = node;
			_tmp12_ = ptr;
			gee_hazard_pointer_node_set (_tmp11_, _tmp12_);
		}
	}
	_tmp13_ = ptr;
	if (_tmp13_ != NULL) {
		GeeHazardPointerNode* _tmp14_ = NULL;
		GeeHazardPointer* _tmp15_ = NULL;
		_tmp14_ = node;
		_tmp15_ = gee_hazard_pointer_new_from_node (_tmp14_);
		result = _tmp15_;
		if (mask_out) {
			*mask_out = _vala_mask_out;
		}
		return result;
	} else {
		GeeHazardPointerNode* _tmp16_ = NULL;
		_tmp16_ = node;
		gee_hazard_pointer_node_release (_tmp16_);
		result = NULL;
		if (mask_out) {
			*mask_out = _vala_mask_out;
		}
		return result;
	}
	if (mask_out) {
		*mask_out = _vala_mask_out;
	}
}


/**
 * Copy an object from atomic pointer.
 *
 * @param aptr Atomic pointer.
 * @param mask Mask of flags.
 * @param mask_out Result of mask.
 * @return A copy of object from atomic pointer.
 */
gpointer gee_hazard_pointer_get_pointer (GType g_type, GBoxedCopyFunc g_dup_func, GDestroyNotify g_destroy_func, gconstpointer** aptr, gsize mask, gsize* mask_out) {
	gsize _vala_mask_out = 0UL;
	gpointer result = NULL;
	GeeHazardPointerNode* node = NULL;
	GeeHazardPointerNode* _tmp0_ = NULL;
	void* rptr = NULL;
	void* ptr = NULL;
	gpointer res = NULL;
	void* _tmp13_ = NULL;
	gpointer _tmp14_ = NULL;
	GeeHazardPointerNode* _tmp15_ = NULL;
	_tmp0_ = gee_hazard_pointer_acquire ();
	node = _tmp0_;
	rptr = NULL;
	ptr = NULL;
	_vala_mask_out = (gsize) 0;
	{
		gboolean _tmp1_ = FALSE;
		_tmp1_ = TRUE;
		while (TRUE) {
			gconstpointer** _tmp5_ = NULL;
			void* _tmp6_ = NULL;
			void* _tmp7_ = NULL;
			gsize _tmp8_ = 0UL;
			void* _tmp9_ = NULL;
			gsize _tmp10_ = 0UL;
			GeeHazardPointerNode* _tmp11_ = NULL;
			void* _tmp12_ = NULL;
			if (!_tmp1_) {
				void* _tmp2_ = NULL;
				gconstpointer** _tmp3_ = NULL;
				void* _tmp4_ = NULL;
				_tmp2_ = rptr;
				_tmp3_ = aptr;
				_tmp4_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) _tmp3_));
				if (!(_tmp2_ != _tmp4_)) {
					break;
				}
			}
			_tmp1_ = FALSE;
			_tmp5_ = aptr;
			_tmp6_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) _tmp5_));
			rptr = _tmp6_;
			_tmp7_ = rptr;
			_tmp8_ = mask;
			ptr = (void*) (((gsize) _tmp7_) & (~_tmp8_));
			_tmp9_ = rptr;
			_tmp10_ = mask;
			_vala_mask_out = ((gsize) _tmp9_) & _tmp10_;
			_tmp11_ = node;
			_tmp12_ = ptr;
			gee_hazard_pointer_node_set (_tmp11_, _tmp12_);
		}
	}
	_tmp13_ = ptr;
	_tmp14_ = ((((gconstpointer*) _tmp13_) != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) ((gconstpointer*) _tmp13_)) : ((gpointer) ((gconstpointer*) _tmp13_));
	res = _tmp14_;
	_tmp15_ = node;
	gee_hazard_pointer_node_release (_tmp15_);
	result = res;
	if (mask_out) {
		*mask_out = _vala_mask_out;
	}
	return result;
}


/**
 * Exchange objects safly.
 *
 * @param aptr Atomic pointer.
 * @param new_ptr New value
 * @param mask Mask of flags.
 * @param new_mask New mask.
 * @param old_mask Previous mask mask.
 * @return Hazard pointer containing old value.
 */
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) {
	gsize _vala_old_mask = 0UL;
	GeeHazardPointer* result = NULL;
	GeeHazardPointerNode* new_node = NULL;
	gconstpointer _tmp0_ = NULL;
	void* new_rptr = NULL;
	gpointer _tmp4_ = NULL;
	gsize _tmp5_ = 0UL;
	gsize _tmp6_ = 0UL;
	GeeHazardPointerNode* node = NULL;
	GeeHazardPointerNode* _tmp7_ = NULL;
	void* rptr = NULL;
	void* ptr = NULL;
	GeeHazardPointerNode* _tmp21_ = NULL;
	void* _tmp23_ = NULL;
	new_node = NULL;
	_tmp0_ = new_ptr;
	if (_tmp0_ != NULL) {
		GeeHazardPointerNode* _tmp1_ = NULL;
		GeeHazardPointerNode* _tmp2_ = NULL;
		gconstpointer _tmp3_ = NULL;
		_tmp1_ = gee_hazard_pointer_acquire ();
		new_node = _tmp1_;
		_tmp2_ = new_node;
		_tmp3_ = new_ptr;
		gee_hazard_pointer_node_set (_tmp2_, _tmp3_);
	}
	_vala_old_mask = (gsize) 0;
	_tmp4_ = new_ptr;
	new_ptr = NULL;
	_tmp5_ = mask;
	_tmp6_ = new_mask;
	new_rptr = (void*) (((gsize) _tmp4_) | (_tmp5_ & _tmp6_));
	_tmp7_ = gee_hazard_pointer_acquire ();
	node = _tmp7_;
	rptr = NULL;
	ptr = NULL;
	{
		gboolean _tmp8_ = FALSE;
		_tmp8_ = TRUE;
		while (TRUE) {
			gconstpointer** _tmp13_ = NULL;
			void* _tmp14_ = NULL;
			void* _tmp15_ = NULL;
			gsize _tmp16_ = 0UL;
			void* _tmp17_ = NULL;
			gsize _tmp18_ = 0UL;
			GeeHazardPointerNode* _tmp19_ = NULL;
			void* _tmp20_ = NULL;
			if (!_tmp8_) {
				gconstpointer** _tmp9_ = NULL;
				void* _tmp10_ = NULL;
				void* _tmp11_ = NULL;
				gboolean _tmp12_ = FALSE;
				_tmp9_ = aptr;
				_tmp10_ = rptr;
				_tmp11_ = new_rptr;
				_tmp12_ = g_atomic_pointer_compare_and_exchange ((volatile gpointer *) ((void**) _tmp9_), _tmp10_, _tmp11_);
				if (!(!_tmp12_)) {
					break;
				}
			}
			_tmp8_ = FALSE;
			_tmp13_ = aptr;
			_tmp14_ = g_atomic_pointer_get ((volatile gpointer *) ((void**) _tmp13_));
			rptr = _tmp14_;
			_tmp15_ = rptr;
			_tmp16_ = mask;
			ptr = (void*) (((gsize) _tmp15_) & (~_tmp16_));
			_tmp17_ = rptr;
			_tmp18_ = mask;
			_vala_old_mask = ((gsize) _tmp17_) & _tmp18_;
			_tmp19_ = node;
			_tmp20_ = ptr;
			gee_hazard_pointer_node_set (_tmp19_, _tmp20_);
		}
	}
	_tmp21_ = new_node;
	if (_tmp21_ != NULL) {
		GeeHazardPointerNode* _tmp22_ = NULL;
		_tmp22_ = new_node;
		gee_hazard_pointer_node_release (_tmp22_);
	}
	_tmp23_ = ptr;
	if (_tmp23_ != NULL) {
		GeeHazardPointerNode* _tmp24_ = NULL;
		GeeHazardPointer* _tmp25_ = NULL;
		_tmp24_ = node;
		_tmp25_ = gee_hazard_pointer_new_from_node (_tmp24_);
		result = _tmp25_;
		_g_destroy_func0 (new_ptr);
		if (old_mask) {
			*old_mask = _vala_old_mask;
		}
		return result;
	} else {
		GeeHazardPointerNode* _tmp26_ = NULL;
		_tmp26_ = node;
		gee_hazard_pointer_node_release (_tmp26_);
		result = NULL;
		_g_destroy_func0 (new_ptr);
		if (old_mask) {
			*old_mask = _vala_old_mask;
		}
		return result;
	}
	_g_destroy_func0 (new_ptr);
	if (old_mask) {
		*old_mask = _vala_old_mask;
	}
}


/**
 * Sets object safely
 *
 * @param aptr Atomic pointer.
 * @param new_ptr New value
 * @param mask Mask of flags.
 * @param new_mask New mask.
 */
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) {
	GeeHazardPointer* ptr = NULL;
	gconstpointer** _tmp0_ = NULL;
	gconstpointer _tmp1_ = NULL;
	gpointer _tmp2_ = NULL;
	gsize _tmp3_ = 0UL;
	gsize _tmp4_ = 0UL;
	GeeHazardPointer* _tmp5_ = NULL;
	GeeHazardPointer* _tmp6_ = NULL;
	_tmp0_ = aptr;
	_tmp1_ = new_ptr;
	_tmp2_ = ((_tmp1_ != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) _tmp1_) : ((gpointer) _tmp1_);
	_tmp3_ = mask;
	_tmp4_ = new_mask;
	_tmp5_ = gee_hazard_pointer_exchange_hazard_pointer (g_type, (GBoxedCopyFunc) g_dup_func, g_destroy_func, _tmp0_, _tmp2_, _tmp3_, _tmp4_, NULL);
	ptr = _tmp5_;
	_tmp6_ = ptr;
	if (_tmp6_ != NULL) {
		GDestroyNotify notify = NULL;
		GDestroyNotify _tmp7_ = NULL;
		GDestroyNotify _tmp8_ = NULL;
		_tmp7_ = gee_utils_free_get_destroy_notify (g_type, (GBoxedCopyFunc) g_dup_func, g_destroy_func);
		notify = _tmp7_;
		_tmp8_ = notify;
		if (_tmp8_ != NULL) {
			GeeHazardPointer* _tmp9_ = NULL;
			GDestroyNotify _tmp10_ = NULL;
			_tmp9_ = ptr;
			_tmp10_ = notify;
			gee_hazard_pointer_release (_tmp9_, _tmp10_);
		}
	}
	_gee_hazard_pointer_free0 (ptr);
	_g_destroy_func0 (new_ptr);
}


/**
 * Exchange objects safly.
 *
 * @param aptr Atomic pointer.
 * @param new_ptr New value
 * @param mask Mask of flags.
 * @param new_mask New mask.
 * @param old_mask Previous mask mask.
 * @return Value that was previously stored.
 */
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) {
	gsize _vala_old_mask = 0UL;
	gpointer result = NULL;
	GeeHazardPointer* ptr = NULL;
	gconstpointer** _tmp0_ = NULL;
	gconstpointer _tmp1_ = NULL;
	gpointer _tmp2_ = NULL;
	gsize _tmp3_ = 0UL;
	gsize _tmp4_ = 0UL;
	gsize _tmp5_ = 0UL;
	GeeHazardPointer* _tmp6_ = NULL;
	gconstpointer _tmp7_ = NULL;
	GeeHazardPointer* _tmp8_ = NULL;
	gpointer rptr = NULL;
	gpointer _tmp11_ = NULL;
	_tmp0_ = aptr;
	_tmp1_ = new_ptr;
	_tmp2_ = ((_tmp1_ != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) _tmp1_) : ((gpointer) _tmp1_);
	_tmp3_ = mask;
	_tmp4_ = new_mask;
	_tmp6_ = gee_hazard_pointer_exchange_hazard_pointer (g_type, (GBoxedCopyFunc) g_dup_func, g_destroy_func, _tmp0_, _tmp2_, _tmp3_, _tmp4_, &_tmp5_);
	_vala_old_mask = _tmp5_;
	ptr = _tmp6_;
	_tmp8_ = ptr;
	if (_tmp8_ != NULL) {
		GeeHazardPointer* _tmp9_ = NULL;
		gconstpointer _tmp10_ = NULL;
		_tmp9_ = ptr;
		_tmp10_ = gee_hazard_pointer_get (_tmp9_, FALSE);
		_tmp7_ = _tmp10_;
	} else {
		_tmp7_ = NULL;
	}
	_tmp11_ = ((_tmp7_ != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) _tmp7_) : ((gpointer) _tmp7_);
	rptr = _tmp11_;
	result = rptr;
	_gee_hazard_pointer_free0 (ptr);
	_g_destroy_func0 (new_ptr);
	if (old_mask) {
		*old_mask = _vala_old_mask;
	}
	return result;
}


/**
 * Compares and exchanges objects.
 *
 * @param aptr Atomic pointer.
 * @param old_ptr Old pointer.
 * @param _new_ptr New value.
 * @param old_mask Old mask.
 * @param new_mask New mask.
 * @return Value that was previously stored.
 */
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) {
	gboolean result = FALSE;
	gconstpointer* new_ptr = NULL;
	gpointer _tmp0_ = NULL;
	void* new_rptr = NULL;
	gconstpointer* _tmp1_ = NULL;
	gsize _tmp2_ = 0UL;
	gsize _tmp3_ = 0UL;
	void* old_rptr = NULL;
	gconstpointer _tmp4_ = NULL;
	gsize _tmp5_ = 0UL;
	gsize _tmp6_ = 0UL;
	gboolean success = FALSE;
	gconstpointer** _tmp7_ = NULL;
	void* _tmp8_ = NULL;
	void* _tmp9_ = NULL;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	_tmp0_ = _new_ptr;
	_new_ptr = NULL;
	new_ptr = _tmp0_;
	_tmp1_ = new_ptr;
	_tmp2_ = mask;
	_tmp3_ = new_mask;
	new_rptr = (void*) (((gsize) _tmp1_) | (_tmp2_ & _tmp3_));
	_tmp4_ = old_ptr;
	_tmp5_ = mask;
	_tmp6_ = old_mask;
	old_rptr = (void*) (((gsize) _tmp4_) | (_tmp5_ & _tmp6_));
	_tmp7_ = aptr;
	_tmp8_ = old_rptr;
	_tmp9_ = new_rptr;
	_tmp10_ = g_atomic_pointer_compare_and_exchange ((volatile gpointer *) ((void**) _tmp7_), _tmp8_, _tmp9_);
	success = _tmp10_;
	_tmp11_ = success;
	if (_tmp11_) {
		GDestroyNotify notify = NULL;
		GDestroyNotify _tmp12_ = NULL;
		gboolean _tmp13_ = FALSE;
		gconstpointer _tmp14_ = NULL;
		_tmp12_ = gee_utils_free_get_destroy_notify (g_type, (GBoxedCopyFunc) g_dup_func, g_destroy_func);
		notify = _tmp12_;
		_tmp14_ = old_ptr;
		if (_tmp14_ != NULL) {
			GDestroyNotify _tmp15_ = NULL;
			_tmp15_ = notify;
			_tmp13_ = _tmp15_ != NULL;
		} else {
			_tmp13_ = FALSE;
		}
		if (_tmp13_) {
			GeeHazardPointerContext* _tmp16_ = NULL;
			gconstpointer _tmp17_ = NULL;
			GDestroyNotify _tmp18_ = NULL;
			_tmp16_ = gee_hazard_pointer_context_get_current_context ();
			_tmp17_ = old_ptr;
			_tmp18_ = notify;
			gee_hazard_pointer_context_release_ptr (_tmp16_, _tmp17_, _tmp18_);
		}
	} else {
		gconstpointer* _tmp19_ = NULL;
		_tmp19_ = new_ptr;
		if (_tmp19_ != NULL) {
			gconstpointer* _tmp20_ = NULL;
			_tmp20_ = new_ptr;
			new_ptr = NULL;
			_g_destroy_func0 (_new_ptr);
			_new_ptr = _tmp20_;
		}
	}
	result = success;
	_g_destroy_func0 (_new_ptr);
	return result;
}


/**
 * Gets the pointer hold by hazard pointer.
 *
 * @param other_thread Have to be set to ``true`` if accessed from thread that did not create this thread.
 * @return The value hold by pointer.
 */
inline gconstpointer gee_hazard_pointer_get (GeeHazardPointer* self, gboolean other_thread) {
	gconstpointer result = NULL;
	GeeHazardPointerNode* _tmp0_ = NULL;
	gboolean _tmp1_ = FALSE;
	void* _tmp2_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->_node;
	_tmp1_ = other_thread;
	_tmp2_ = gee_hazard_pointer_node_get (_tmp0_, _tmp1_);
	result = _tmp2_;
	return result;
}


/**
 * Free the pointer.
 *
 * @param notify method freeing object
 */
void gee_hazard_pointer_release (GeeHazardPointer* self, GDestroyNotify notify) {
	gconstpointer item = NULL;
	GeeHazardPointerNode* _tmp0_ = NULL;
	void* _tmp1_ = NULL;
	GeeHazardPointerNode* _tmp2_ = NULL;
	gconstpointer _tmp3_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->_node;
	_tmp1_ = gee_hazard_pointer_node_get (_tmp0_, FALSE);
	item = _tmp1_;
	_tmp2_ = self->_node;
	gee_hazard_pointer_node_set (_tmp2_, NULL);
	_tmp3_ = item;
	if (_tmp3_ != NULL) {
		GeeHazardPointerContext* _tmp4_ = NULL;
		gconstpointer _tmp5_ = NULL;
		GDestroyNotify _tmp6_ = NULL;
		_tmp4_ = gee_hazard_pointer_context_get_current_context ();
		_tmp5_ = item;
		_tmp6_ = notify;
		gee_hazard_pointer_context_release_ptr (_tmp4_, _tmp5_, _tmp6_);
	}
}


/**
 * Sets default policy (i.e. default policy for user-created contexts).
 * The policy must be concrete and should not be blocking.
 *
 * @param policy New default policy.
 */
void gee_hazard_pointer_set_default_policy (GeeHazardPointerPolicy policy) {
	GeeHazardPointerPolicy _tmp0_ = 0;
	gboolean _tmp1_ = FALSE;
	GeeHazardPointerPolicy _tmp2_ = 0;
	gboolean _tmp3_ = FALSE;
	GeeHazardPointerPolicy _tmp4_ = 0;
	_tmp0_ = policy;
	_tmp1_ = gee_hazard_pointer_policy_is_concrete (_tmp0_);
	_vala_return_if_fail (_tmp1_, "policy.is_concrete ()");
	_tmp2_ = policy;
	_tmp3_ = gee_hazard_pointer_policy_is_blocking (_tmp2_);
	if (_tmp3_) {
		g_warning ("hazardpointer.vala:252: Setting blocking defautl Gee.HazardPointer.Pol" \
"icy (there may be a deadlock).\n");
	}
	_tmp4_ = policy;
	g_atomic_int_set ((volatile gint *) (&gee_hazard_pointer__default_policy), (gint) _tmp4_);
}


/**
 * Sets thread exit policy (i.e. default policy for the top-most Context).
 * The policy must be concrete and should not be unsafe.
 *
 * @param policy New thread policy.
 */
void gee_hazard_pointer_set_thread_exit_policy (GeeHazardPointerPolicy policy) {
	GeeHazardPointerPolicy _tmp0_ = 0;
	gboolean _tmp1_ = FALSE;
	GeeHazardPointerPolicy _tmp2_ = 0;
	gboolean _tmp3_ = FALSE;
	GeeHazardPointerPolicy _tmp4_ = 0;
	_tmp0_ = policy;
	_tmp1_ = gee_hazard_pointer_policy_is_concrete (_tmp0_);
	_vala_return_if_fail (_tmp1_, "policy.is_concrete ()");
	_tmp2_ = policy;
	_tmp3_ = gee_hazard_pointer_policy_is_safe (_tmp2_);
	if (!_tmp3_) {
		g_warning ("hazardpointer.vala:264: Setting unsafe globale thread-exit Gee.HazardP" \
"ointer.Policy (there may be a memory leak).\n");
	}
	_tmp4_ = policy;
	g_atomic_int_set ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy), (gint) _tmp4_);
}


/**
 * Sets release (i.e. how exactly the released objects arefreed).
 *
 * The method can be only set before any objects is released and is not thread-safe.
 *
 * @param policy New release policy.
 */
gboolean gee_hazard_pointer_set_release_policy (GeeHazardPointerReleasePolicy policy) {
	gboolean result = FALSE;
	gint old_policy = 0;
	gint _tmp0_ = 0;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	GeeHazardPointerReleasePolicy _tmp3_ = 0;
	gboolean _tmp4_ = FALSE;
	_tmp0_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer_release_policy));
	old_policy = _tmp0_;
	_tmp1_ = old_policy;
	if ((_tmp1_ & ((sizeof (gint) * 8) - 1)) != 0) {
		g_critical ("hazardpointer.vala:278: Attempt to change the policy of running helper" \
". Failing.");
		result = FALSE;
		return result;
	}
	_tmp2_ = old_policy;
	_tmp3_ = policy;
	_tmp4_ = g_atomic_int_compare_and_exchange ((volatile gint *) (&gee_hazard_pointer_release_policy), _tmp2_, (gint) _tmp3_);
	if (!_tmp4_) {
		g_critical ("hazardpointer.vala:282: Concurrent access to release policy detected. " \
"Failing.");
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


/**
 * Gets a new hazard pointer node.
 *
 * @return new hazard pointer node.
 */
G_GNUC_INTERNAL inline GeeHazardPointerNode* gee_hazard_pointer_acquire (void) {
	GeeHazardPointerNode* result = NULL;
	GeeHazardPointerNode* node = NULL;
	GeeHazardPointerNode* _tmp8_ = NULL;
	GeeHazardPointerNode* old_head = NULL;
	GeeHazardPointerNode* _tmp16_ = NULL;
	{
		GeeHazardPointerNode* curr = NULL;
		GeeHazardPointerNode* _tmp0_ = NULL;
		_tmp0_ = gee_hazard_pointer_get_head ();
		curr = _tmp0_;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GeeHazardPointerNode* _tmp4_ = NULL;
				GeeHazardPointerNode* _tmp5_ = NULL;
				gboolean _tmp6_ = FALSE;
				if (!_tmp1_) {
					GeeHazardPointerNode* _tmp2_ = NULL;
					GeeHazardPointerNode* _tmp3_ = NULL;
					_tmp2_ = curr;
					_tmp3_ = gee_hazard_pointer_node_get_next (_tmp2_);
					curr = _tmp3_;
				}
				_tmp1_ = FALSE;
				_tmp4_ = curr;
				if (!(_tmp4_ != NULL)) {
					break;
				}
				_tmp5_ = curr;
				_tmp6_ = gee_hazard_pointer_node_activate (_tmp5_);
				if (_tmp6_) {
					GeeHazardPointerNode* _tmp7_ = NULL;
					_tmp7_ = curr;
					result = _tmp7_;
					return result;
				}
			}
		}
	}
	_tmp8_ = gee_hazard_pointer_node_new ();
	node = _tmp8_;
	old_head = NULL;
	{
		gboolean _tmp9_ = FALSE;
		_tmp9_ = TRUE;
		while (TRUE) {
			GeeHazardPointerNode* _tmp13_ = NULL;
			void* _tmp14_ = NULL;
			GeeHazardPointerNode* _tmp15_ = NULL;
			if (!_tmp9_) {
				GeeHazardPointerNode* _tmp10_ = NULL;
				GeeHazardPointerNode* _tmp11_ = NULL;
				gboolean _tmp12_ = FALSE;
				_tmp10_ = old_head;
				_tmp11_ = node;
				_tmp12_ = g_atomic_pointer_compare_and_exchange ((volatile gpointer *) (&gee_hazard_pointer__head), _tmp10_, _tmp11_);
				if (!(!_tmp12_)) {
					break;
				}
			}
			_tmp9_ = FALSE;
			_tmp13_ = node;
			_tmp14_ = g_atomic_pointer_get ((volatile gpointer *) (&gee_hazard_pointer__head));
			old_head = (GeeHazardPointerNode*) _tmp14_;
			_tmp15_ = old_head;
			gee_hazard_pointer_node_set_next (_tmp13_, _tmp15_);
		}
	}
	_tmp16_ = node;
	result = _tmp16_;
	return result;
}


/**
 * Tries to free from list.
 *
 * @return ``true`` if list is empty.
 */
G_GNUC_INTERNAL gboolean gee_hazard_pointer_try_free (GeeArrayList* to_free) {
	gboolean result = FALSE;
	GeeCollection* used = NULL;
	GeeHashSet* _tmp0_ = NULL;
	GeeArrayList* _tmp43_ = NULL;
	gint _tmp44_ = 0;
	gint _tmp45_ = 0;
	g_return_val_if_fail (to_free != NULL, FALSE);
	_tmp0_ = gee_hash_set_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	used = (GeeCollection*) _tmp0_;
	{
		GeeHazardPointerNode* current = NULL;
		GeeHazardPointerNode* _tmp1_ = NULL;
		_tmp1_ = gee_hazard_pointer_get_head ();
		current = _tmp1_;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				GeeHazardPointerNode* _tmp5_ = NULL;
				GeeCollection* _tmp6_ = NULL;
				GeeHazardPointerNode* _tmp7_ = NULL;
				void* _tmp8_ = NULL;
				if (!_tmp2_) {
					GeeHazardPointerNode* _tmp3_ = NULL;
					GeeHazardPointerNode* _tmp4_ = NULL;
					_tmp3_ = current;
					_tmp4_ = gee_hazard_pointer_node_get_next (_tmp3_);
					current = _tmp4_;
				}
				_tmp2_ = FALSE;
				_tmp5_ = current;
				if (!(_tmp5_ != NULL)) {
					break;
				}
				_tmp6_ = used;
				_tmp7_ = current;
				_tmp8_ = gee_hazard_pointer_node_get (_tmp7_, TRUE);
				gee_collection_add (_tmp6_, _tmp8_);
			}
		}
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp9_ = FALSE;
			_tmp9_ = TRUE;
			while (TRUE) {
				gint _tmp10_ = 0;
				GeeArrayList* _tmp11_ = NULL;
				gint _tmp12_ = 0;
				gint _tmp13_ = 0;
				GeeHazardPointerFreeNode* current = NULL;
				GeeArrayList* _tmp14_ = NULL;
				gint _tmp15_ = 0;
				gpointer _tmp16_ = NULL;
				GeeCollection* _tmp17_ = NULL;
				GeeHazardPointerFreeNode* _tmp18_ = NULL;
				void* _tmp19_ = NULL;
				gboolean _tmp20_ = FALSE;
				if (!_tmp9_) {
				}
				_tmp9_ = FALSE;
				_tmp10_ = i;
				_tmp11_ = to_free;
				_tmp12_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp11_);
				_tmp13_ = _tmp12_;
				if (!(_tmp10_ < _tmp13_)) {
					break;
				}
				_tmp14_ = to_free;
				_tmp15_ = i;
				_tmp16_ = gee_abstract_list_get ((GeeAbstractList*) _tmp14_, _tmp15_);
				current = _tmp16_;
				_tmp17_ = used;
				_tmp18_ = current;
				_tmp19_ = _tmp18_->pointer;
				_tmp20_ = gee_collection_contains (_tmp17_, _tmp19_);
				if (_tmp20_) {
					gint _tmp21_ = 0;
					_tmp21_ = i;
					i = _tmp21_ + 1;
				} else {
					GeeHazardPointerFreeNode* cur = NULL;
					GeeArrayList* _tmp22_ = NULL;
					GeeArrayList* _tmp23_ = NULL;
					gint _tmp24_ = 0;
					gint _tmp25_ = 0;
					gpointer _tmp26_ = NULL;
					gint _tmp27_ = 0;
					GeeArrayList* _tmp28_ = NULL;
					gint _tmp29_ = 0;
					gint _tmp30_ = 0;
					GeeHazardPointerFreeNode* _tmp38_ = NULL;
					GDestroyNotify _tmp39_ = NULL;
					GeeHazardPointerFreeNode* _tmp40_ = NULL;
					void* _tmp41_ = NULL;
					GeeHazardPointerFreeNode* _tmp42_ = NULL;
					_tmp22_ = to_free;
					_tmp23_ = to_free;
					_tmp24_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp23_);
					_tmp25_ = _tmp24_;
					_tmp26_ = gee_abstract_list_remove_at ((GeeAbstractList*) _tmp22_, _tmp25_ - 1);
					cur = _tmp26_;
					_tmp27_ = i;
					_tmp28_ = to_free;
					_tmp29_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp28_);
					_tmp30_ = _tmp29_;
					if (_tmp27_ != _tmp30_) {
						GeeHazardPointerFreeNode* temp = NULL;
						GeeArrayList* _tmp31_ = NULL;
						gint _tmp32_ = 0;
						gpointer _tmp33_ = NULL;
						GeeArrayList* _tmp34_ = NULL;
						gint _tmp35_ = 0;
						GeeHazardPointerFreeNode* _tmp36_ = NULL;
						GeeHazardPointerFreeNode* _tmp37_ = NULL;
						_tmp31_ = to_free;
						_tmp32_ = i;
						_tmp33_ = gee_abstract_list_get ((GeeAbstractList*) _tmp31_, _tmp32_);
						temp = _tmp33_;
						_tmp34_ = to_free;
						_tmp35_ = i;
						_tmp36_ = cur;
						gee_abstract_list_set ((GeeAbstractList*) _tmp34_, _tmp35_, _tmp36_);
						_tmp37_ = temp;
						cur = _tmp37_;
					}
					_tmp38_ = cur;
					_tmp39_ = _tmp38_->destroy_notify;
					_tmp40_ = cur;
					_tmp41_ = _tmp40_->pointer;
					_tmp39_ (_tmp41_);
					_tmp42_ = cur;
					gee_hazard_pointer_free_node_free (_tmp42_);
				}
			}
		}
	}
	_tmp43_ = to_free;
	_tmp44_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp43_);
	_tmp45_ = _tmp44_;
	result = _tmp45_ > 0;
	_g_object_unref0 (used);
	return result;
}


/**
 * Gets head of hazard pointers.
 * @return Hazard pointer head.
 */
G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_get_head (void) {
	GeeHazardPointerNode* result = NULL;
	void* _tmp0_ = NULL;
	_tmp0_ = g_atomic_pointer_get ((volatile gpointer *) (&gee_hazard_pointer__head));
	result = (GeeHazardPointerNode*) _tmp0_;
	return result;
}


static GeeHazardPointerPolicy* _gee_hazard_pointer_policy_dup (GeeHazardPointerPolicy* self) {
	GeeHazardPointerPolicy* dup;
	dup = g_new0 (GeeHazardPointerPolicy, 1);
	memcpy (dup, self, sizeof (GeeHazardPointerPolicy));
	return dup;
}


static gpointer __gee_hazard_pointer_policy_dup0 (gpointer self) {
	return self ? _gee_hazard_pointer_policy_dup (self) : NULL;
}


GeeHazardPointerContext* gee_hazard_pointer_context_new (GeeHazardPointerPolicy* policy) {
	GeeHazardPointerContext* self;
	GeeArrayList* _tmp0_ = NULL;
	void* _tmp1_ = NULL;
	GeeHazardPointerPolicy* _tmp2_ = NULL;
	self = g_slice_new0 (GeeHazardPointerContext);
	gee_hazard_pointer_context_instance_init (self);
	_tmp0_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->_to_free);
	self->_to_free = _tmp0_;
	_tmp1_ = g_static_private_get (&gee_hazard_pointer_context__current_context);
	self->_parent = _tmp1_;
	g_static_private_set (&gee_hazard_pointer_context__current_context, self, NULL);
	_tmp2_ = policy;
	if (_tmp2_ == NULL) {
		GeeHazardPointerContext* _tmp3_ = NULL;
		_tmp3_ = self->_parent;
		if (_tmp3_ == NULL) {
			gint _tmp4_ = 0;
			GeeHazardPointerPolicy _tmp5_ = 0;
			GeeHazardPointerPolicy* _tmp6_ = NULL;
			_tmp4_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__thread_exit_policy));
			_tmp5_ = (GeeHazardPointerPolicy) _tmp4_;
			_tmp6_ = __gee_hazard_pointer_policy_dup0 (&_tmp5_);
			_g_free0 (self->_policy);
			self->_policy = _tmp6_;
		} else {
			gint _tmp7_ = 0;
			GeeHazardPointerPolicy _tmp8_ = 0;
			GeeHazardPointerPolicy* _tmp9_ = NULL;
			_tmp7_ = g_atomic_int_get ((volatile gint *) (&gee_hazard_pointer__default_policy));
			_tmp8_ = (GeeHazardPointerPolicy) _tmp7_;
			_tmp9_ = __gee_hazard_pointer_policy_dup0 (&_tmp8_);
			_g_free0 (self->_policy);
			self->_policy = _tmp9_;
		}
	} else {
		GeeHazardPointerPolicy* _tmp10_ = NULL;
		GeeHazardPointerPolicy _tmp11_ = 0;
		GeeHazardPointerPolicy* _tmp12_ = NULL;
		_tmp10_ = policy;
		_tmp11_ = gee_hazard_pointer_policy_to_concrete (*_tmp10_);
		_tmp12_ = __gee_hazard_pointer_policy_dup0 (&_tmp11_);
		_g_free0 (self->_policy);
		self->_policy = _tmp12_;
	}
	return self;
}


/**
 * Tries to free all freed pointer in current context.
 */
void gee_hazard_pointer_context_try_free (GeeHazardPointerContext* self) {
	GeeArrayList* _tmp0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->_to_free;
	gee_hazard_pointer_try_free (_tmp0_);
}


/**
 * Ensure that whole context is freed. Plase note that it might block.
 */
void gee_hazard_pointer_context_free_all (GeeHazardPointerContext* self) {
	g_return_if_fail (self != NULL);
	while (TRUE) {
		GeeArrayList* _tmp0_ = NULL;
		gboolean _tmp1_ = FALSE;
		_tmp0_ = self->_to_free;
		_tmp1_ = gee_hazard_pointer_try_free (_tmp0_);
		if (!_tmp1_) {
			break;
		}
		g_thread_yield ();
	}
}


/**
 * Tries to push the current context to releaser.
 */
void gee_hazard_pointer_context_try_release (GeeHazardPointerContext* self) {
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_static_mutex_trylock (&gee_hazard_pointer__queue_mutex);
	if (_tmp0_) {
		GeeQueue* _tmp1_ = NULL;
		GeeArrayList* _tmp2_ = NULL;
		GeeArrayList* _tmp3_ = NULL;
		GeeArrayList* _tmp4_ = NULL;
		_tmp1_ = gee_hazard_pointer__queue;
		_tmp2_ = self->_to_free;
		self->_to_free = NULL;
		_tmp3_ = _tmp2_;
		gee_queue_offer (_tmp1_, _tmp3_);
		_g_object_unref0 (_tmp3_);
		_tmp4_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
		_g_object_unref0 (self->_to_free);
		self->_to_free = _tmp4_;
		g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
	}
}


/**
 * Pushes the current context to releaser. Plase note that it might block.
 */
void gee_hazard_pointer_context_release (GeeHazardPointerContext* self) {
	GeeQueue* _tmp0_ = NULL;
	GeeArrayList* _tmp1_ = NULL;
	GeeArrayList* _tmp2_ = NULL;
	GeeArrayList* _tmp3_ = NULL;
	g_return_if_fail (self != NULL);
	g_static_mutex_lock (&gee_hazard_pointer__queue_mutex);
	_tmp0_ = gee_hazard_pointer__queue;
	_tmp1_ = self->_to_free;
	self->_to_free = NULL;
	_tmp2_ = _tmp1_;
	gee_queue_offer (_tmp0_, _tmp2_);
	_g_object_unref0 (_tmp2_);
	_tmp3_ = gee_array_list_new (G_TYPE_POINTER, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->_to_free);
	self->_to_free = _tmp3_;
	g_static_mutex_unlock (&gee_hazard_pointer__queue_mutex);
}


/**
 * Add pointer to freed array.
 */
G_GNUC_INTERNAL inline void gee_hazard_pointer_context_release_ptr (GeeHazardPointerContext* self, void* ptr, GDestroyNotify notify) {
	GeeHazardPointerFreeNode* node = NULL;
	GeeHazardPointerFreeNode* _tmp0_ = NULL;
	GeeHazardPointerFreeNode* _tmp1_ = NULL;
	void* _tmp2_ = NULL;
	GeeHazardPointerFreeNode* _tmp3_ = NULL;
	GDestroyNotify _tmp4_ = NULL;
	GeeArrayList* _tmp5_ = NULL;
	GeeHazardPointerFreeNode* _tmp6_ = NULL;
	GeeArrayList* _tmp7_ = NULL;
	gint _tmp8_ = 0;
	gint _tmp9_ = 0;
	guint _tmp10_ = 0U;
	g_return_if_fail (self != NULL);
	_tmp0_ = gee_hazard_pointer_free_node_new ();
	node = _tmp0_;
	_tmp1_ = node;
	_tmp2_ = ptr;
	_tmp1_->pointer = _tmp2_;
	_tmp3_ = node;
	_tmp4_ = notify;
	_tmp3_->destroy_notify = _tmp4_;
	_tmp5_ = self->_to_free;
	_tmp6_ = node;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp5_, _tmp6_);
	_tmp7_ = self->_to_free;
	_tmp8_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp7_);
	_tmp9_ = _tmp8_;
	_tmp10_ = gee_hazard_pointer_context_THRESHOLD;
	if (((guint) _tmp9_) >= _tmp10_) {
		GeeArrayList* _tmp11_ = NULL;
		_tmp11_ = self->_to_free;
		gee_hazard_pointer_try_free (_tmp11_);
	}
}


/**
 * Gets current context.
 */
G_GNUC_INTERNAL inline GeeHazardPointerContext* gee_hazard_pointer_context_get_current_context (void) {
	GeeHazardPointerContext* result = NULL;
	void* _tmp0_ = NULL;
	_tmp0_ = g_static_private_get (&gee_hazard_pointer_context__current_context);
	result = _tmp0_;
	return result;
}


static void gee_hazard_pointer_context_instance_init (GeeHazardPointerContext * self) {
}


void gee_hazard_pointer_context_free (GeeHazardPointerContext* self) {
	gint size = 0;
	GeeArrayList* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gboolean clean_parent = FALSE;
	gint _tmp3_ = 0;
	GeeHazardPointerContext* _tmp16_ = NULL;
	gboolean _tmp17_ = FALSE;
	_tmp0_ = self->_to_free;
	_tmp1_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	size = _tmp2_;
	clean_parent = FALSE;
	_tmp3_ = size;
	if (_tmp3_ > 0) {
		gboolean _tmp4_ = FALSE;
		GeeHazardPointerContext* _tmp5_ = NULL;
		_tmp5_ = self->_parent;
		if (_tmp5_ == NULL) {
			_tmp4_ = TRUE;
		} else {
			gint _tmp6_ = 0;
			guint _tmp7_ = 0U;
			_tmp6_ = size;
			_tmp7_ = gee_hazard_pointer_context_THRESHOLD;
			_tmp4_ = ((guint) _tmp6_) >= _tmp7_;
		}
		if (_tmp4_) {
			GeeHazardPointerPolicy* _tmp8_ = NULL;
			gboolean _tmp9_ = FALSE;
			_tmp8_ = self->_policy;
			_tmp9_ = gee_hazard_pointer_policy_perform (*_tmp8_, &self->_to_free);
			if (!_tmp9_) {
				gboolean _tmp10_ = FALSE;
				GeeHazardPointerContext* _tmp11_ = NULL;
				GeeHazardPointerContext* _tmp13_ = NULL;
				GeeArrayList* _tmp14_ = NULL;
				GeeArrayList* _tmp15_ = NULL;
				_tmp11_ = self->_parent;
				if (_tmp11_ != NULL) {
					GeeArrayList* _tmp12_ = NULL;
					_tmp12_ = self->_to_free;
					_tmp10_ = _tmp12_ != NULL;
				} else {
					_tmp10_ = FALSE;
				}
				_vala_assert (_tmp10_, "_parent != null && _to_free != null");
				_tmp13_ = self->_parent;
				_tmp14_ = _tmp13_->_to_free;
				_tmp15_ = self->_to_free;
				gee_array_list_add_all (_tmp14_, (GeeCollection*) _tmp15_);
				clean_parent = TRUE;
			}
		}
	}
	_tmp16_ = self->_parent;
	g_static_private_set (&gee_hazard_pointer_context__current_context, _tmp16_, NULL);
	_tmp17_ = clean_parent;
	if (_tmp17_) {
		GeeHazardPointerContext* _tmp18_ = NULL;
		GeeArrayList* _tmp19_ = NULL;
		_tmp18_ = self->_parent;
		_tmp19_ = _tmp18_->_to_free;
		gee_hazard_pointer_try_free (_tmp19_);
	}
	_g_object_unref0 (self->_to_free);
	_g_free0 (self->_policy);
	g_slice_free (GeeHazardPointerContext, self);
}


G_GNUC_INTERNAL GeeHazardPointerFreeNode* gee_hazard_pointer_free_node_new (void) {
	GeeHazardPointerFreeNode* self;
	self = g_slice_new0 (GeeHazardPointerFreeNode);
	gee_hazard_pointer_free_node_instance_init (self);
	return self;
}


static void gee_hazard_pointer_free_node_instance_init (GeeHazardPointerFreeNode * self) {
}


G_GNUC_INTERNAL void gee_hazard_pointer_free_node_free (GeeHazardPointerFreeNode* self) {
	g_slice_free (GeeHazardPointerFreeNode, self);
}


G_GNUC_INTERNAL GeeHazardPointerNode* gee_hazard_pointer_node_new (void) {
	GeeHazardPointerNode* self;
	self = g_slice_new0 (GeeHazardPointerNode);
	gee_hazard_pointer_node_instance_init (self);
	g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), NULL);
	g_atomic_int_set ((volatile gint *) (&self->_active), 1);
	return self;
}


G_GNUC_INTERNAL void gee_hazard_pointer_node_release (GeeHazardPointerNode* self) {
	g_return_if_fail (self != NULL);
	g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), NULL);
	g_atomic_int_set ((volatile gint *) (&self->_active), 0);
}


G_GNUC_INTERNAL inline gboolean gee_hazard_pointer_node_is_active (GeeHazardPointerNode* self) {
	gboolean result = FALSE;
	gint _tmp0_ = 0;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = g_atomic_int_get ((volatile gint *) (&self->_active));
	result = _tmp0_ != 0;
	return result;
}


G_GNUC_INTERNAL inline gboolean gee_hazard_pointer_node_activate (GeeHazardPointerNode* self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = g_atomic_int_compare_and_exchange ((volatile gint *) (&self->_active), 0, 1);
	result = _tmp0_;
	return result;
}


G_GNUC_INTERNAL inline void gee_hazard_pointer_node_set (GeeHazardPointerNode* self, void* ptr) {
	void* _tmp0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = ptr;
	g_atomic_pointer_set ((volatile gpointer *) (&self->_hazard), _tmp0_);
}


G_GNUC_INTERNAL inline void* gee_hazard_pointer_node_get (GeeHazardPointerNode* self, gboolean safe) {
	void* result = NULL;
	gboolean _tmp0_ = FALSE;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = safe;
	if (_tmp0_) {
		void* _tmp1_ = NULL;
		_tmp1_ = g_atomic_pointer_get ((volatile gpointer *) (&self->_hazard));
		result = (void*) _tmp1_;
		return result;
	} else {
		void* _tmp2_ = NULL;
		_tmp2_ = self->_hazard;
		result = (void*) _tmp2_;
		return result;
	}
}


G_GNUC_INTERNAL inline GeeHazardPointerNode* gee_hazard_pointer_node_get_next (GeeHazardPointerNode* self) {
	GeeHazardPointerNode* result = NULL;
	void* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_atomic_pointer_get ((volatile gpointer *) (&self->_next));
	result = (GeeHazardPointerNode*) _tmp0_;
	return result;
}


G_GNUC_INTERNAL inline void gee_hazard_pointer_node_set_next (GeeHazardPointerNode* self, GeeHazardPointerNode* next) {
	GeeHazardPointerNode* _tmp0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = next;
	g_atomic_pointer_set ((volatile gpointer *) (&self->_next), _tmp0_);
}


static void gee_hazard_pointer_node_instance_init (GeeHazardPointerNode * self) {
}


G_GNUC_INTERNAL void gee_hazard_pointer_node_free (GeeHazardPointerNode* self) {
	GeeHazardPointerNode* _tmp0_ = NULL;
	_tmp0_ = self->_next;
	gee_hazard_pointer_node_free (_tmp0_);
	g_slice_free (GeeHazardPointerNode, self);
}


static void gee_hazard_pointer_instance_init (GeeHazardPointer * self) {
}


void gee_hazard_pointer_free (GeeHazardPointer* self) {
	GeeHazardPointerNode* _tmp0_ = NULL;
	_tmp0_ = self->_node;
	gee_hazard_pointer_node_release (_tmp0_);
	g_slice_free (GeeHazardPointer, self);
}



