/*
 * This file is part of gtkD.
 *
 * gtkD 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 3
 * of the License, or (at your option) any later version, with
 * some exceptions, please read the COPYING file.
 *
 * gtkD 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 gtkD; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
 */

// generated automatically - do not change
// find conversion definition on APILookup.txt
// implement new conversion functionalities the gir-to-d pakage


module glib.Thread;

private import glib.ConstructionException;
private import glib.ErrorG;
private import glib.GException;
private import glib.Str;
private import glib.c.functions;
public  import glib.c.types;


/**
 * The #GThread struct represents a running thread. This struct
 * is returned by g_thread_new() or g_thread_try_new(). You can
 * obtain the #GThread struct representing the current thread by
 * calling g_thread_self().
 * 
 * GThread is refcounted, see g_thread_ref() and g_thread_unref().
 * The thread represented by it holds a reference while it is running,
 * and g_thread_join() consumes the reference that it is given, so
 * it is normally not necessary to manage GThread references
 * explicitly.
 * 
 * The structure is opaque -- none of its fields may be directly
 * accessed.
 */
public class Thread
{
	/** the main Gtk struct */
	protected GThread* gThread;
	protected bool ownedRef;

	/** Get the main Gtk struct */
	public GThread* getThreadStruct(bool transferOwnership = false)
	{
		if (transferOwnership)
			ownedRef = false;
		return gThread;
	}

	/** the main Gtk struct as a void* */
	protected void* getStruct()
	{
		return cast(void*)gThread;
	}

	/**
	 * Sets our main struct and passes it to the parent class.
	 */
	public this (GThread* gThread, bool ownedRef = false)
	{
		this.gThread = gThread;
		this.ownedRef = ownedRef;
	}

	~this ()
	{
		if ( ownedRef )
			g_thread_unref(gThread);
	}


	/**
	 * This function is the same as g_thread_new() except that
	 * it allows for the possibility of failure.
	 *
	 * If a thread can not be created (due to resource limits),
	 * @error is set and %NULL is returned.
	 *
	 * Params:
	 *     name = an (optional) name for the new thread
	 *     func = a function to execute in the new thread
	 *     data = an argument to supply to the new thread
	 *
	 * Returns: the new #GThread, or %NULL if an error occurred
	 *
	 * Since: 2.32
	 *
	 * Throws: GException on failure.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this(string name, GThreadFunc func, void* data)
	{
		GError* err = null;

		auto __p = g_thread_try_new(Str.toStringz(name), func, data, &err);

		if (err !is null)
		{
			throw new GException( new ErrorG(err) );
		}

		if(__p is null)
		{
			throw new ConstructionException("null returned by try_new");
		}

		this(cast(GThread*) __p);
	}

	/**
	 * Gets the name of the thread.
	 *
	 * This function is intended for debugging purposes.
	 *
	 * Returns: the name of the thread
	 *
	 * Since: 2.84
	 */
	public string getName()
	{
		return Str.toString(g_thread_get_name(gThread));
	}

	/**
	 * Waits until @thread finishes, i.e. the function @func, as
	 * given to g_thread_new(), returns or g_thread_exit() is called.
	 * If @thread has already terminated, then g_thread_join()
	 * returns immediately.
	 *
	 * Any thread can wait for any other thread by calling g_thread_join(),
	 * not just its 'creator'. Calling g_thread_join() from multiple threads
	 * for the same @thread leads to undefined behaviour.
	 *
	 * The value returned by @func or given to g_thread_exit() is
	 * returned by this function.
	 *
	 * g_thread_join() consumes the reference to the passed-in @thread.
	 * This will usually cause the #GThread struct and associated resources
	 * to be freed. Use g_thread_ref() to obtain an extra reference if you
	 * want to keep the GThread alive beyond the g_thread_join() call.
	 *
	 * Returns: the return value of the thread
	 */
	public void* join()
	{
		return g_thread_join(gThread);
	}

	alias doref = ref_;
	/**
	 * Increase the reference count on @thread.
	 *
	 * Returns: a new reference to @thread
	 *
	 * Since: 2.32
	 */
	public Thread ref_()
	{
		auto __p = g_thread_ref(gThread);

		if(__p is null)
		{
			return null;
		}

		return new Thread(cast(GThread*) __p, true);
	}

	/**
	 * This function does nothing.
	 *
	 * Deprecated: Thread priorities no longer have any effect.
	 *
	 * Params:
	 *     priority = ignored
	 */
	public void setPriority(GThreadPriority priority)
	{
		g_thread_set_priority(gThread, priority);
	}

	/**
	 * Decrease the reference count on @thread, possibly freeing all
	 * resources associated with it.
	 *
	 * Note that each thread holds a reference to its #GThread while
	 * it is running, so it is safe to drop your own reference to it
	 * if you don't need it anymore.
	 *
	 * Since: 2.32
	 */
	public void unref()
	{
		g_thread_unref(gThread);
	}

	/**
	 * This function creates a new thread.
	 *
	 * The new thread executes the function @func with the argument @data.
	 * If the thread was created successfully, it is returned.
	 *
	 * @error can be %NULL to ignore errors, or non-%NULL to report errors.
	 * The error is set, if and only if the function returns %NULL.
	 *
	 * This function returns a reference to the created thread only if
	 * @joinable is %TRUE.  In that case, you must free this reference by
	 * calling g_thread_unref() or g_thread_join().  If @joinable is %FALSE
	 * then you should probably not touch the return value.
	 *
	 * Deprecated: Use g_thread_new() instead
	 *
	 * Params:
	 *     func = a function to execute in the new thread
	 *     data = an argument to supply to the new thread
	 *     joinable = should this thread be joinable?
	 *
	 * Returns: the new #GThread on success
	 *
	 * Throws: GException on failure.
	 */
	public static Thread create(GThreadFunc func, void* data, bool joinable)
	{
		GError* err = null;

		auto __p = g_thread_create(func, data, joinable, &err);

		if (err !is null)
		{
			throw new GException( new ErrorG(err) );
		}

		if(__p is null)
		{
			return null;
		}

		return new Thread(cast(GThread*) __p, true);
	}

	/**
	 * This function creates a new thread.
	 *
	 * Deprecated: The @bound and @priority arguments are now ignored.
	 * Use g_thread_new().
	 *
	 * Params:
	 *     func = a function to execute in the new thread.
	 *     data = an argument to supply to the new thread.
	 *     stackSize = a stack size for the new thread.
	 *     joinable = should this thread be joinable?
	 *     bound = ignored
	 *     priority = ignored
	 *
	 * Returns: the new #GThread on success.
	 *
	 * Throws: GException on failure.
	 */
	public static Thread createFull(GThreadFunc func, void* data, gulong stackSize, bool joinable, bool bound, GThreadPriority priority)
	{
		GError* err = null;

		auto __p = g_thread_create_full(func, data, stackSize, joinable, bound, priority, &err);

		if (err !is null)
		{
			throw new GException( new ErrorG(err) );
		}

		if(__p is null)
		{
			return null;
		}

		return new Thread(cast(GThread*) __p, true);
	}

	/** */
	public static GQuark errorQuark()
	{
		return g_thread_error_quark();
	}

	/**
	 * Terminates the current thread.
	 *
	 * If another thread is waiting for us using g_thread_join() then the
	 * waiting thread will be woken up and get @retval as the return value
	 * of g_thread_join().
	 *
	 * Calling g_thread_exit() with a parameter @retval is equivalent to
	 * returning @retval from the function @func, as given to g_thread_new().
	 *
	 * You must only call g_thread_exit() from a thread that you created
	 * yourself with g_thread_new() or related APIs. You must not call
	 * this function from a thread created with another threading library
	 * or or from within a #GThreadPool.
	 *
	 * Params:
	 *     retval = the return value of this thread
	 */
	public static void exit(void* retval)
	{
		g_thread_exit(retval);
	}

	alias foreac = foreach_;
	/**
	 * Call @thread_func on all #GThreads that have been
	 * created with g_thread_create().
	 *
	 * Note that threads may decide to exit while @thread_func is
	 * running, so without intimate knowledge about the lifetime of
	 * foreign threads, @thread_func shouldn't access the GThread*
	 * pointer passed in as first argument. However, @thread_func will
	 * not be called for threads which are known to have exited already.
	 *
	 * Due to thread lifetime checks, this function has an execution complexity
	 * which is quadratic in the number of existing threads.
	 *
	 * Deprecated: There aren't many things you can do with a #GThread,
	 * except comparing it with one that was returned from g_thread_create().
	 * There are better ways to find out if your thread is still alive.
	 *
	 * Params:
	 *     threadFunc = function to call for all #GThread structures
	 *     userData = second argument to @thread_func
	 *
	 * Since: 2.10
	 */
	public static void foreach_(GFunc threadFunc, void* userData)
	{
		g_thread_foreach(threadFunc, userData);
	}

	/**
	 * Indicates if g_thread_init() has been called.
	 *
	 * Returns: %TRUE if threads have been initialized.
	 *
	 * Since: 2.20
	 */
	public static bool getInitialized()
	{
		return g_thread_get_initialized() != 0;
	}

	/**
	 * If you use GLib from more than one thread, you must initialize the
	 * thread system by calling g_thread_init().
	 *
	 * Since version 2.24, calling g_thread_init() multiple times is allowed,
	 * but nothing happens except for the first call.
	 *
	 * Since version 2.32, GLib does not support custom thread implementations
	 * anymore and the @vtable parameter is ignored and you should pass %NULL.
	 *
	 * ::: note
	 * g_thread_init() must not be called directly or indirectly in a
	 * callback from GLib. Also no mutexes may be currently locked
	 * while calling g_thread_init().
	 *
	 * ::: note
	 * To use g_thread_init() in your program, you have to link with
	 * the libraries that the command `pkg-config --libs gthread-2.0`
	 * outputs. This is not the case for all the other thread-related
	 * functions of GLib. Those can be used without having to link
	 * with the thread libraries.
	 *
	 * Deprecated: This function is no longer necessary. The GLib
	 * threading system is automatically initialized at the start
	 * of your program.
	 *
	 * Params:
	 *     vtable = a function table of type #GThreadFunctions, that provides
	 *         the entry points to the thread system to be used. Since 2.32,
	 *         this parameter is ignored and should always be %NULL
	 */
	public static void init(void* vtable)
	{
		g_thread_init(vtable);
	}

	/** */
	public static void initWithErrorcheckMutexes(void* vtable)
	{
		g_thread_init_with_errorcheck_mutexes(vtable);
	}

	/**
	 * This function returns the #GThread corresponding to the
	 * current thread. Note that this function does not increase
	 * the reference count of the returned struct.
	 *
	 * This function will return a #GThread even for threads that
	 * were not created by GLib (i.e. those created by other threading
	 * APIs). This may be useful for thread identification purposes
	 * (i.e. comparisons) but you must not use GLib functions (such
	 * as g_thread_join()) on these threads.
	 *
	 * Returns: the #GThread representing the current thread
	 */
	public static Thread self()
	{
		auto __p = g_thread_self();

		if(__p is null)
		{
			return null;
		}

		return new Thread(cast(GThread*) __p);
	}

	/**
	 * Causes the calling thread to voluntarily relinquish the CPU, so
	 * that other threads can run.
	 *
	 * This function is often used as a method to make busy wait less evil.
	 */
	public static void yield()
	{
		g_thread_yield();
	}

	/**
	 * Sets the indicated @lock_bit in @address.  If the bit is already
	 * set, this call will block until g_bit_unlock() unsets the
	 * corresponding bit.
	 *
	 * Attempting to lock on two different bits within the same integer is
	 * not supported and will very probably cause deadlocks.
	 *
	 * The value of the bit that is set is (1u << @bit).  If @bit is not
	 * between 0 and 31 then the result is undefined.
	 *
	 * This function accesses @address atomically.  All other accesses to
	 * @address must be atomic in order for this function to work
	 * reliably. While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to an integer
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Since: 2.24
	 */
	public static void bitLock(int* address, int lockBit)
	{
		g_bit_lock(address, lockBit);
	}

	/**
	 * Sets the indicated @lock_bit in @address, returning %TRUE if
	 * successful.  If the bit is already set, returns %FALSE immediately.
	 *
	 * Attempting to lock on two different bits within the same integer is
	 * not supported.
	 *
	 * The value of the bit that is set is (1u << @bit).  If @bit is not
	 * between 0 and 31 then the result is undefined.
	 *
	 * This function accesses @address atomically.  All other accesses to
	 * @address must be atomic in order for this function to work
	 * reliably. While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to an integer
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Returns: %TRUE if the lock was acquired
	 *
	 * Since: 2.24
	 */
	public static bool bitTrylock(int* address, int lockBit)
	{
		return g_bit_trylock(address, lockBit) != 0;
	}

	/**
	 * Clears the indicated @lock_bit in @address.  If another thread is
	 * currently blocked in g_bit_lock() on this same bit then it will be
	 * woken up.
	 *
	 * This function accesses @address atomically.  All other accesses to
	 * @address must be atomic in order for this function to work
	 * reliably. While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to an integer
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Since: 2.24
	 */
	public static void bitUnlock(int* address, int lockBit)
	{
		g_bit_unlock(address, lockBit);
	}

	/**
	 * Determine the approximate number of threads that the system will
	 * schedule simultaneously for this process.  This is intended to be
	 * used as a parameter to g_thread_pool_new() for CPU bound tasks and
	 * similar cases.
	 *
	 * Returns: Number of schedulable threads, always greater than 0
	 *
	 * Since: 2.36
	 */
	public static uint getNumProcessors()
	{
		return g_get_num_processors();
	}

	/**
	 * This is equivalent to g_bit_lock, but working on pointers (or other
	 * pointer-sized values).
	 *
	 * For portability reasons, you may only lock on the bottom 32 bits of
	 * the pointer.
	 *
	 * While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to a #gpointer-sized value
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Since: 2.30
	 */
	public static void pointerBitLock(void* address, int lockBit)
	{
		g_pointer_bit_lock(address, lockBit);
	}

	/**
	 * This is equivalent to g_bit_trylock(), but working on pointers (or
	 * other pointer-sized values).
	 *
	 * For portability reasons, you may only lock on the bottom 32 bits of
	 * the pointer.
	 *
	 * While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to a #gpointer-sized value
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Returns: %TRUE if the lock was acquired
	 *
	 * Since: 2.30
	 */
	public static bool pointerBitTrylock(void* address, int lockBit)
	{
		return g_pointer_bit_trylock(address, lockBit) != 0;
	}

	/**
	 * This is equivalent to g_bit_unlock, but working on pointers (or other
	 * pointer-sized values).
	 *
	 * For portability reasons, you may only lock on the bottom 32 bits of
	 * the pointer.
	 *
	 * While @address has a `volatile` qualifier, this is a historical
	 * artifact and the argument passed to it should not be `volatile`.
	 *
	 * Params:
	 *     address = a pointer to a #gpointer-sized value
	 *     lockBit = a bit value between 0 and 31
	 *
	 * Since: 2.30
	 */
	public static void pointerBitUnlock(void* address, int lockBit)
	{
		g_pointer_bit_unlock(address, lockBit);
	}
}
