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 or blocks waiting for it, the current 181 * thread will block. Read locks can be taken recursively. 182 * 183 * It is implementation-defined how many threads are allowed to 184 * hold read locks on the same lock simultaneously. If the limit is hit, 185 * or if a deadlock is detected, a critical warning will be emitted. 186 * 187 * Since: 2.32 188 */ 189 public void readerLock() 190 { 191 g_rw_lock_reader_lock(gRWLock); 192 } 193 194 /** 195 * Tries to obtain a read lock on @rw_lock and returns %TRUE if 196 * the read lock was successfully obtained. Otherwise it 197 * returns %FALSE. 198 * 199 * Returns: %TRUE if @rw_lock could be locked 200 * 201 * Since: 2.32 202 */ 203 public bool readerTrylock() 204 { 205 return g_rw_lock_reader_trylock(gRWLock) != 0; 206 } 207 208 /** 209 * Release a read lock on @rw_lock. 210 * 211 * Calling g_rw_lock_reader_unlock() on a lock that is not held 212 * by the current thread leads to undefined behaviour. 213 * 214 * Since: 2.32 215 */ 216 public void readerUnlock() 217 { 218 g_rw_lock_reader_unlock(gRWLock); 219 } 220 221 /** 222 * Obtain a write lock on @rw_lock. If any thread already holds 223 * a read or write lock on @rw_lock, the current thread will block 224 * until all other threads have dropped their locks on @rw_lock. 225 * 226 * Since: 2.32 227 */ 228 public void writerLock() 229 { 230 g_rw_lock_writer_lock(gRWLock); 231 } 232 233 /** 234 * Tries to obtain a write lock on @rw_lock. If any other thread holds 235 * a read or write lock on @rw_lock, it immediately returns %FALSE. 236 * Otherwise it locks @rw_lock and returns %TRUE. 237 * 238 * Returns: %TRUE if @rw_lock could be locked 239 * 240 * Since: 2.32 241 */ 242 public bool writerTrylock() 243 { 244 return g_rw_lock_writer_trylock(gRWLock) != 0; 245 } 246 247 /** 248 * Release a write lock on @rw_lock. 249 * 250 * Calling g_rw_lock_writer_unlock() on a lock that is not held 251 * by the current thread leads to undefined behaviour. 252 * 253 * Since: 2.32 254 */ 255 public void writerUnlock() 256 { 257 g_rw_lock_writer_unlock(gRWLock); 258 } 259 }