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 }