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 }