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 public  import gtkc.glibtypes;
30 
31 
32 /**
33  * The GRWLock struct is an opaque data structure to represent a
34  * reader-writer lock. It is similar to a #GMutex in that it allows
35  * multiple threads to coordinate access to a shared resource.
36  * 
37  * The difference to a mutex is that a reader-writer lock discriminates
38  * between read-only ('reader') and full ('writer') access. While only
39  * one thread at a time is allowed write access (by holding the 'writer'
40  * lock via g_rw_lock_writer_lock()), multiple threads can gain
41  * simultaneous read-only access (by holding the 'reader' lock via
42  * g_rw_lock_reader_lock()).
43  * 
44  * It is unspecified whether readers or writers have priority in acquiring the
45  * lock when a reader already holds the lock and a writer is queued to acquire
46  * it.
47  * 
48  * Here is an example for an array with access functions:
49  * |[<!-- language="C" -->
50  * GRWLock lock;
51  * GPtrArray *array;
52  * 
53  * gpointer
54  * my_array_get (guint index)
55  * {
56  * gpointer retval = NULL;
57  * 
58  * if (!array)
59  * return NULL;
60  * 
61  * g_rw_lock_reader_lock (&lock);
62  * if (index < array->len)
63  * retval = g_ptr_array_index (array, index);
64  * g_rw_lock_reader_unlock (&lock);
65  * 
66  * return retval;
67  * }
68  * 
69  * void
70  * my_array_set (guint index, gpointer data)
71  * {
72  * g_rw_lock_writer_lock (&lock);
73  * 
74  * if (!array)
75  * array = g_ptr_array_new ();
76  * 
77  * if (index >= array->len)
78  * g_ptr_array_set_size (array, index+1);
79  * g_ptr_array_index (array, index) = data;
80  * 
81  * g_rw_lock_writer_unlock (&lock);
82  * }
83  * ]|
84  * This example shows an array which can be accessed by many readers
85  * (the my_array_get() function) simultaneously, whereas the writers
86  * (the my_array_set() function) will only be allowed one at a time
87  * and only if no readers currently access the array. This is because
88  * of the potentially dangerous resizing of the array. Using these
89  * functions is fully multi-thread safe now.
90  * 
91  * If a #GRWLock is allocated in static storage then it can be used
92  * without initialisation.  Otherwise, you should call
93  * g_rw_lock_init() on it and g_rw_lock_clear() when done.
94  * 
95  * A GRWLock should only be accessed with the g_rw_lock_ functions.
96  *
97  * Since: 2.32
98  */
99 public class RWLock
100 {
101 	/** the main Gtk struct */
102 	protected GRWLock* gRWLock;
103 	protected bool ownedRef;
104 
105 	/** Get the main Gtk struct */
106 	public GRWLock* getRWLockStruct(bool transferOwnership = false)
107 	{
108 		if (transferOwnership)
109 			ownedRef = false;
110 		return gRWLock;
111 	}
112 
113 	/** the main Gtk struct as a void* */
114 	protected void* getStruct()
115 	{
116 		return cast(void*)gRWLock;
117 	}
118 
119 	/**
120 	 * Sets our main struct and passes it to the parent class.
121 	 */
122 	public this (GRWLock* gRWLock, bool ownedRef = false)
123 	{
124 		this.gRWLock = gRWLock;
125 		this.ownedRef = ownedRef;
126 	}
127 
128 
129 	/**
130 	 * Frees the resources allocated to a lock with g_rw_lock_init().
131 	 *
132 	 * This function should not be used with a #GRWLock that has been
133 	 * statically allocated.
134 	 *
135 	 * Calling g_rw_lock_clear() when any thread holds the lock
136 	 * leads to undefined behaviour.
137 	 *
138 	 * Sine: 2.32
139 	 */
140 	public void clear()
141 	{
142 		g_rw_lock_clear(gRWLock);
143 	}
144 
145 	/**
146 	 * Initializes a #GRWLock so that it can be used.
147 	 *
148 	 * This function is useful to initialize a lock that has been
149 	 * allocated on the stack, or as part of a larger structure.  It is not
150 	 * necessary to initialise a reader-writer lock that has been statically
151 	 * allocated.
152 	 *
153 	 * |[<!-- language="C" -->
154 	 * typedef struct {
155 	 * GRWLock l;
156 	 * ...
157 	 * } Blob;
158 	 *
159 	 * Blob *b;
160 	 *
161 	 * b = g_new (Blob, 1);
162 	 * g_rw_lock_init (&b->l);
163 	 * ]|
164 	 *
165 	 * To undo the effect of g_rw_lock_init() when a lock is no longer
166 	 * needed, use g_rw_lock_clear().
167 	 *
168 	 * Calling g_rw_lock_init() on an already initialized #GRWLock leads
169 	 * to undefined behaviour.
170 	 *
171 	 * Since: 2.32
172 	 */
173 	public void init()
174 	{
175 		g_rw_lock_init(gRWLock);
176 	}
177 
178 	/**
179 	 * Obtain a read lock on @rw_lock. If another thread currently holds
180 	 * the write lock on @rw_lock, the current thread will block. If another thread
181 	 * does not hold the write lock, but is waiting for it, it is implementation
182 	 * defined whether the reader or writer will block. Read locks can be taken
183 	 * recursively.
184 	 *
185 	 * It is implementation-defined how many threads are allowed to
186 	 * hold read locks on the same lock simultaneously. If the limit is hit,
187 	 * or if a deadlock is detected, a critical warning will be emitted.
188 	 *
189 	 * Since: 2.32
190 	 */
191 	public void readerLock()
192 	{
193 		g_rw_lock_reader_lock(gRWLock);
194 	}
195 
196 	/**
197 	 * Tries to obtain a read lock on @rw_lock and returns %TRUE if
198 	 * the read lock was successfully obtained. Otherwise it
199 	 * returns %FALSE.
200 	 *
201 	 * Returns: %TRUE if @rw_lock could be locked
202 	 *
203 	 * Since: 2.32
204 	 */
205 	public bool readerTrylock()
206 	{
207 		return g_rw_lock_reader_trylock(gRWLock) != 0;
208 	}
209 
210 	/**
211 	 * Release a read lock on @rw_lock.
212 	 *
213 	 * Calling g_rw_lock_reader_unlock() on a lock that is not held
214 	 * by the current thread leads to undefined behaviour.
215 	 *
216 	 * Since: 2.32
217 	 */
218 	public void readerUnlock()
219 	{
220 		g_rw_lock_reader_unlock(gRWLock);
221 	}
222 
223 	/**
224 	 * Obtain a write lock on @rw_lock. If any thread already holds
225 	 * a read or write lock on @rw_lock, the current thread will block
226 	 * until all other threads have dropped their locks on @rw_lock.
227 	 *
228 	 * Since: 2.32
229 	 */
230 	public void writerLock()
231 	{
232 		g_rw_lock_writer_lock(gRWLock);
233 	}
234 
235 	/**
236 	 * Tries to obtain a write lock on @rw_lock. If any other thread holds
237 	 * a read or write lock on @rw_lock, it immediately returns %FALSE.
238 	 * Otherwise it locks @rw_lock and returns %TRUE.
239 	 *
240 	 * Returns: %TRUE if @rw_lock could be locked
241 	 *
242 	 * Since: 2.32
243 	 */
244 	public bool writerTrylock()
245 	{
246 		return g_rw_lock_writer_trylock(gRWLock) != 0;
247 	}
248 
249 	/**
250 	 * Release a write lock on @rw_lock.
251 	 *
252 	 * Calling g_rw_lock_writer_unlock() on a lock that is not held
253 	 * by the current thread leads to undefined behaviour.
254 	 *
255 	 * Since: 2.32
256 	 */
257 	public void writerUnlock()
258 	{
259 		g_rw_lock_writer_unlock(gRWLock);
260 	}
261 }