/*
 * 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.StaticRWLock;

private import glib.c.functions;
public  import glib.c.types;


/**
 * The #GStaticRWLock struct represents a read-write lock. A read-write
 * lock can be used for protecting data that some portions of code only
 * read from, while others also write. In such situations it is
 * desirable that several readers can read at once, whereas of course
 * only one writer may write at a time.
 * 
 * Take a look at the following example:
 * |[
 * GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
 * GPtrArray *array;
 * 
 * gpointer
 * my_array_get (guint index)
 * {
 * gpointer retval = NULL;
 * 
 * if (!array)
 * return NULL;
 * 
 * g_static_rw_lock_reader_lock (&rwlock);
 * if (index < array->len)
 * retval = g_ptr_array_index (array, index);
 * g_static_rw_lock_reader_unlock (&rwlock);
 * 
 * return retval;
 * }
 * 
 * void
 * my_array_set (guint index, gpointer data)
 * {
 * g_static_rw_lock_writer_lock (&rwlock);
 * 
 * if (!array)
 * array = g_ptr_array_new ();
 * 
 * if (index >= array->len)
 * g_ptr_array_set_size (array, index + 1);
 * g_ptr_array_index (array, index) = data;
 * 
 * g_static_rw_lock_writer_unlock (&rwlock);
 * }
 * ]|
 * 
 * This example shows an array which can be accessed by many readers
 * (the my_array_get() function) simultaneously, whereas the writers
 * (the my_array_set() function) will only be allowed once at a time
 * and only if no readers currently access the array. This is because
 * of the potentially dangerous resizing of the array. Using these
 * functions is fully multi-thread safe now.
 * 
 * Most of the time, writers should have precedence over readers. That
 * means, for this implementation, that as soon as a writer wants to
 * lock the data, no other reader is allowed to lock the data, whereas,
 * of course, the readers that already have locked the data are allowed
 * to finish their operation. As soon as the last reader unlocks the
 * data, the writer will lock it.
 * 
 * Even though #GStaticRWLock is not opaque, it should only be used
 * with the following functions.
 * 
 * All of the g_static_rw_lock_* functions can be used even if
 * g_thread_init() has not been called. Then they do nothing, apart
 * from g_static_rw_lock_*_trylock, which does nothing but returning %TRUE.
 * 
 * A read-write lock has a higher overhead than a mutex. For example, both
 * g_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock() have
 * to lock and unlock a #GStaticMutex, so it takes at least twice the time
 * to lock and unlock a #GStaticRWLock that it does to lock and unlock a
 * #GStaticMutex. So only data structures that are accessed by multiple
 * readers, and which keep the lock for a considerable time justify a
 * #GStaticRWLock. The above example most probably would fare better with a
 * #GStaticMutex.
 * 
 * Deprecated: Use a #GRWLock instead
 */
public class StaticRWLock
{
	/** the main Gtk struct */
	protected GStaticRWLock* gStaticRWLock;
	protected bool ownedRef;

	/** Get the main Gtk struct */
	public GStaticRWLock* getStaticRWLockStruct(bool transferOwnership = false)
	{
		if (transferOwnership)
			ownedRef = false;
		return gStaticRWLock;
	}

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

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

	~this ()
	{
		if ( ownedRef )
			g_static_rw_lock_free(gStaticRWLock);
	}


	/**
	 * Releases all resources allocated to @lock.
	 *
	 * You don't have to call this functions for a #GStaticRWLock with an
	 * unbounded lifetime, i.e. objects declared 'static', but if you have
	 * a #GStaticRWLock as a member of a structure, and the structure is
	 * freed, you should also free the #GStaticRWLock.
	 *
	 * Deprecated: Use a #GRWLock instead
	 */
	public void free()
	{
		g_static_rw_lock_free(gStaticRWLock);
		ownedRef = false;
	}

	/**
	 * A #GStaticRWLock must be initialized with this function before it
	 * can be used. Alternatively you can initialize it with
	 * %G_STATIC_RW_LOCK_INIT.
	 *
	 * Deprecated: Use g_rw_lock_init() instead
	 */
	public void init()
	{
		g_static_rw_lock_init(gStaticRWLock);
	}

	/**
	 * Locks @lock for reading. There may be unlimited concurrent locks for
	 * reading of a #GStaticRWLock at the same time.  If @lock is already
	 * locked for writing by another thread or if another thread is already
	 * waiting to lock @lock for writing, this function will block until
	 * @lock is unlocked by the other writing thread and no other writing
	 * threads want to lock @lock. This lock has to be unlocked by
	 * g_static_rw_lock_reader_unlock().
	 *
	 * #GStaticRWLock is not recursive. It might seem to be possible to
	 * recursively lock for reading, but that can result in a deadlock, due
	 * to writer preference.
	 *
	 * Deprecated: Use g_rw_lock_reader_lock() instead
	 */
	public void readerLock()
	{
		g_static_rw_lock_reader_lock(gStaticRWLock);
	}

	/**
	 * Tries to lock @lock for reading. If @lock is already locked for
	 * writing by another thread or if another thread is already waiting to
	 * lock @lock for writing, immediately returns %FALSE. Otherwise locks
	 * @lock for reading and returns %TRUE. This lock has to be unlocked by
	 * g_static_rw_lock_reader_unlock().
	 *
	 * Deprecated: Use g_rw_lock_reader_trylock() instead
	 *
	 * Returns: %TRUE, if @lock could be locked for reading
	 */
	public bool readerTrylock()
	{
		return g_static_rw_lock_reader_trylock(gStaticRWLock) != 0;
	}

	/**
	 * Unlocks @lock. If a thread waits to lock @lock for writing and all
	 * locks for reading have been unlocked, the waiting thread is woken up
	 * and can lock @lock for writing.
	 *
	 * Deprecated: Use g_rw_lock_reader_unlock() instead
	 */
	public void readerUnlock()
	{
		g_static_rw_lock_reader_unlock(gStaticRWLock);
	}

	/**
	 * Locks @lock for writing. If @lock is already locked for writing or
	 * reading by other threads, this function will block until @lock is
	 * completely unlocked and then lock @lock for writing. While this
	 * functions waits to lock @lock, no other thread can lock @lock for
	 * reading. When @lock is locked for writing, no other thread can lock
	 * @lock (neither for reading nor writing). This lock has to be
	 * unlocked by g_static_rw_lock_writer_unlock().
	 *
	 * Deprecated: Use g_rw_lock_writer_lock() instead
	 */
	public void writerLock()
	{
		g_static_rw_lock_writer_lock(gStaticRWLock);
	}

	/**
	 * Tries to lock @lock for writing. If @lock is already locked (for
	 * either reading or writing) by another thread, it immediately returns
	 * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This
	 * lock has to be unlocked by g_static_rw_lock_writer_unlock().
	 *
	 * Deprecated: Use g_rw_lock_writer_trylock() instead
	 *
	 * Returns: %TRUE, if @lock could be locked for writing
	 */
	public bool writerTrylock()
	{
		return g_static_rw_lock_writer_trylock(gStaticRWLock) != 0;
	}

	/**
	 * Unlocks @lock. If a thread is waiting to lock @lock for writing and
	 * all locks for reading have been unlocked, the waiting thread is
	 * woken up and can lock @lock for writing. If no thread is waiting to
	 * lock @lock for writing, and some thread or threads are waiting to
	 * lock @lock for reading, the waiting threads are woken up and can
	 * lock @lock for reading.
	 *
	 * Deprecated: Use g_rw_lock_writer_unlock() instead
	 */
	public void writerUnlock()
	{
		g_static_rw_lock_writer_unlock(gStaticRWLock);
	}
}
