1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module glib.RWLock;
26 
27 private import glib.c.functions;
28 public  import glib.c.types;
29 
30 
31 /**
32  * The GRWLock struct is an opaque data structure to represent a
33  * reader-writer lock. It is similar to a #GMutex in that it allows
34  * multiple threads to coordinate access to a shared resource.
35  * 
36  * The difference to a mutex is that a reader-writer lock discriminates
37  * between read-only ('reader') and full ('writer') access. While only
38  * one thread at a time is allowed write access (by holding the 'writer'
39  * lock via g_rw_lock_writer_lock()), multiple threads can gain
40  * simultaneous read-only access (by holding the 'reader' lock via
41  * g_rw_lock_reader_lock()).
42  * 
43  * It is unspecified whether readers or writers have priority in acquiring the
44  * lock when a reader already holds the lock and a writer is queued to acquire
45  * it.
46  * 
47  * Here is an example for an array with access functions:
48  * |[<!-- language="C" -->
49  * GRWLock lock;
50  * GPtrArray *array;
51  * 
52  * gpointer
53  * my_array_get (guint index)
54  * {
55  * gpointer retval = NULL;
56  * 
57  * if (!array)
58  * return NULL;
59  * 
60  * g_rw_lock_reader_lock (&lock);
61  * if (index < array->len)
62  * retval = g_ptr_array_index (array, index);
63  * g_rw_lock_reader_unlock (&lock);
64  * 
65  * return retval;
66  * }
67  * 
68  * void
69  * my_array_set (guint index, gpointer data)
70  * {
71  * g_rw_lock_writer_lock (&lock);
72  * 
73  * if (!array)
74  * array = g_ptr_array_new ();
75  * 
76  * if (index >= array->len)
77  * g_ptr_array_set_size (array, index+1);
78  * g_ptr_array_index (array, index) = data;
79  * 
80  * g_rw_lock_writer_unlock (&lock);
81  * }
82  * ]|
83  * This example shows an array which can be accessed by many readers
84  * (the my_array_get() function) simultaneously, whereas the writers
85  * (the my_array_set() function) will only be allowed one at a time
86  * and only if no readers currently access the array. This is because
87  * of the potentially dangerous resizing of the array. Using these
88  * functions is fully multi-thread safe now.
89  * 
90  * If a #GRWLock is allocated in static storage then it can be used
91  * without initialisation.  Otherwise, you should call
92  * g_rw_lock_init() on it and g_rw_lock_clear() when done.
93  * 
94  * A GRWLock should only be accessed with the g_rw_lock_ functions.
95  *
96  * Since: 2.32
97  */
98 public class RWLock
99 {
100 	/** the main Gtk struct */
101 	protected GRWLock* gRWLock;
102 	protected bool ownedRef;
103 
104 	/** Get the main Gtk struct */
105 	public GRWLock* getRWLockStruct(bool transferOwnership = false)
106 	{
107 		if (transferOwnership)
108 			ownedRef = false;
109 		return gRWLock;
110 	}
111 
112 	/** the main Gtk struct as a void* */
113 	protected void* getStruct()
114 	{
115 		return cast(void*)gRWLock;
116 	}
117 
118 	/**
119 	 * Sets our main struct and passes it to the parent class.
120 	 */
121 	public this (GRWLock* gRWLock, bool ownedRef = false)
122 	{
123 		this.gRWLock = gRWLock;
124 		this.ownedRef = ownedRef;
125 	}
126 
127 
128 	/**
129 	 * Frees the resources allocated to a lock with g_rw_lock_init().
130 	 *
131 	 * This function should not be used with a #GRWLock that has been
132 	 * statically allocated.
133 	 *
134 	 * Calling g_rw_lock_clear() when any thread holds the lock
135 	 * leads to undefined behaviour.
136 	 *
137 	 * Sine: 2.32
138 	 */
139 	public void clear()
140 	{
141 		g_rw_lock_clear(gRWLock);
142 	}
143 
144 	/**
145 	 * Initializes a #GRWLock so that it can be used.
146 	 *
147 	 * This function is useful to initialize a lock that has been
148 	 * allocated on the stack, or as part of a larger structure.  It is not
149 	 * necessary to initialise a reader-writer lock that has been statically
150 	 * allocated.
151 	 *
152 	 * |[<!-- language="C" -->
153 	 * typedef struct {
154 	 * GRWLock l;
155 	 * ...
156 	 * } Blob;
157 	 *
158 	 * Blob *b;
159 	 *
160 	 * b = g_new (Blob, 1);
161 	 * g_rw_lock_init (&b->l);
162 	 * ]|
163 	 *
164 	 * To undo the effect of g_rw_lock_init() when a lock is no longer
165 	 * needed, use g_rw_lock_clear().
166 	 *
167 	 * Calling g_rw_lock_init() on an already initialized #GRWLock leads
168 	 * to undefined behaviour.
169 	 *
170 	 * Since: 2.32
171 	 */
172 	public void init()
173 	{
174 		g_rw_lock_init(gRWLock);
175 	}
176 
177 	/**
178 	 * Obtain a read lock on @rw_lock. If another thread currently holds
179 	 * the write lock on @rw_lock, the current thread will block until the
180 	 * write lock was (held and) released. If another thread does not hold
181 	 * the write lock, but is waiting for it, it is implementation defined
182 	 * whether the reader or writer will block. Read locks can be taken
183 	 * recursively.
184 	 *
185 	 * Calling g_rw_lock_reader_lock() while the current thread already
186 	 * owns a write lock leads to undefined behaviour. Read locks however
187 	 * can be taken recursively, in which case you need to make sure to
188 	 * call g_rw_lock_reader_unlock() the same amount of times.
189 	 *
190 	 * It is implementation-defined how many read locks are allowed to be
191 	 * held on the same lock simultaneously. If the limit is hit,
192 	 * or if a deadlock is detected, a critical warning will be emitted.
193 	 *
194 	 * Since: 2.32
195 	 */
196 	public void readerLock()
197 	{
198 		g_rw_lock_reader_lock(gRWLock);
199 	}
200 
201 	/**
202 	 * Tries to obtain a read lock on @rw_lock and returns %TRUE if
203 	 * the read lock was successfully obtained. Otherwise it
204 	 * returns %FALSE.
205 	 *
206 	 * Returns: %TRUE if @rw_lock could be locked
207 	 *
208 	 * Since: 2.32
209 	 */
210 	public bool readerTrylock()
211 	{
212 		return g_rw_lock_reader_trylock(gRWLock) != 0;
213 	}
214 
215 	/**
216 	 * Release a read lock on @rw_lock.
217 	 *
218 	 * Calling g_rw_lock_reader_unlock() on a lock that is not held
219 	 * by the current thread leads to undefined behaviour.
220 	 *
221 	 * Since: 2.32
222 	 */
223 	public void readerUnlock()
224 	{
225 		g_rw_lock_reader_unlock(gRWLock);
226 	}
227 
228 	/**
229 	 * Obtain a write lock on @rw_lock. If another thread currently holds
230 	 * a read or write lock on @rw_lock, the current thread will block
231 	 * until all other threads have dropped their locks on @rw_lock.
232 	 *
233 	 * Calling g_rw_lock_writer_lock() while the current thread already
234 	 * owns a read or write lock on @rw_lock leads to undefined behaviour.
235 	 *
236 	 * Since: 2.32
237 	 */
238 	public void writerLock()
239 	{
240 		g_rw_lock_writer_lock(gRWLock);
241 	}
242 
243 	/**
244 	 * Tries to obtain a write lock on @rw_lock. If another thread
245 	 * currently holds a read or write lock on @rw_lock, it immediately
246 	 * returns %FALSE.
247 	 * Otherwise it locks @rw_lock and returns %TRUE.
248 	 *
249 	 * Returns: %TRUE if @rw_lock could be locked
250 	 *
251 	 * Since: 2.32
252 	 */
253 	public bool writerTrylock()
254 	{
255 		return g_rw_lock_writer_trylock(gRWLock) != 0;
256 	}
257 
258 	/**
259 	 * Release a write lock on @rw_lock.
260 	 *
261 	 * Calling g_rw_lock_writer_unlock() on a lock that is not held
262 	 * by the current thread leads to undefined behaviour.
263 	 *
264 	 * Since: 2.32
265 	 */
266 	public void writerUnlock()
267 	{
268 		g_rw_lock_writer_unlock(gRWLock);
269 	}
270 }