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 * Conversion parameters: 26 * inFile = 27 * outPack = gthread 28 * outFile = Thread 29 * strct = GThread 30 * realStrct= 31 * ctorStrct= 32 * clss = Thread 33 * interf = 34 * class Code: No 35 * interface Code: No 36 * template for: 37 * extend = 38 * implements: 39 * prefixes: 40 * - g_thread_ 41 * - g_ 42 * omit structs: 43 * omit prefixes: 44 * - g_mutex_ 45 * - g_static_mutex_ 46 * - g_static_rec_mutex_ 47 * - g_static_rw_lock_ 48 * - g_cond_ 49 * - g_private_ 50 * - g_static_private_ 51 * omit code: 52 * omit signals: 53 * imports: 54 * - glib.ErrorG 55 * - glib.GException 56 * structWrap: 57 * - GThread* -> Thread 58 * module aliases: 59 * local aliases: 60 * overrides: 61 */ 62 63 module gthread.Thread; 64 65 public import gtkc.gthreadtypes; 66 67 private import gtkc.gthread; 68 private import glib.ConstructionException; 69 70 71 private import glib.ErrorG; 72 private import glib.GException; 73 74 75 76 77 /** 78 * Description 79 * Threads act almost like processes, but unlike processes all threads 80 * of one process share the same memory. This is good, as it provides 81 * easy communication between the involved threads via this shared 82 * memory, and it is bad, because strange things (so called 83 * "Heisenbugs") might happen if the program is not carefully designed. 84 * In particular, due to the concurrent nature of threads, no 85 * assumptions on the order of execution of code running in different 86 * threads can be made, unless order is explicitly forced by the 87 * programmer through synchronization primitives. 88 * The aim of the thread related functions in GLib is to provide a 89 * portable means for writing multi-threaded software. There are 90 * primitives for mutexes to protect the access to portions of memory 91 * (GMutex, GStaticMutex, G_LOCK_DEFINE, GStaticRecMutex and 92 * GStaticRWLock). There are primitives for condition variables to 93 * allow synchronization of threads (GCond). There are primitives for 94 * thread-private data - data that every thread has a private instance 95 * of (GPrivate, GStaticPrivate). Last but definitely not least there 96 * are primitives to portably create and manage threads (GThread). 97 * The threading system is initialized with g_thread_init(), which 98 * takes an optional custom thread implementation or NULL for the 99 * default implementation. If you want to call g_thread_init() with a 100 * non-NULL argument this must be done before executing any other GLib 101 * functions (except g_mem_set_vtable()). This is a requirement even if 102 * no threads are in fact ever created by the process. 103 * Calling g_thread_init() with a NULL argument is somewhat more 104 * relaxed. You may call any other glib functions in the main thread 105 * before g_thread_init() as long as g_thread_init() is not called from 106 * a glib callback, or with any locks held. However, many libraries 107 * above glib does not support late initialization of threads, so doing 108 * this should be avoided if possible. 109 * Please note that since version 2.24 the GObject initialization 110 * function g_type_init() initializes threads (with a NULL argument), 111 * so most applications, including those using Gtk+ will run with 112 * threads enabled. If you want a special thread implementation, make 113 * sure you call g_thread_init() before g_type_init() is called. 114 * After calling g_thread_init(), GLib is completely thread safe (all 115 * global data is automatically locked), but individual data structure 116 * instances are not automatically locked for performance reasons. So, 117 * for example you must coordinate accesses to the same GHashTable 118 * from multiple threads. The two notable exceptions from this rule 119 * are GMainLoop and GAsyncQueue, which are 120 * threadsafe and need no further application-level locking to be 121 * accessed from multiple threads. 122 * To help debugging problems in multithreaded applications, GLib 123 * supports error-checking mutexes that will give you helpful error 124 * messages on common problems. To use error-checking mutexes, define 125 * the symbol G_ERRORCHECK_MUTEXES when compiling the application. 126 */ 127 public class Thread 128 { 129 130 /** the main Gtk struct */ 131 protected GThread* gThread; 132 133 134 public GThread* getThreadStruct() 135 { 136 return gThread; 137 } 138 139 140 /** the main Gtk struct as a void* */ 141 protected void* getStruct() 142 { 143 return cast(void*)gThread; 144 } 145 146 /** 147 * Sets our main struct and passes it to the parent class 148 */ 149 public this (GThread* gThread) 150 { 151 this.gThread = gThread; 152 } 153 154 /** 155 */ 156 157 /** 158 * If you use GLib from more than one thread, you must initialize the 159 * thread system by calling g_thread_init(). Most of the time you will 160 * only have to call g_thread_init (NULL). 161 * Note 162 * Do not call g_thread_init() with a non-NULL parameter unless 163 * you really know what you are doing. 164 * Note 165 * g_thread_init() must not be called directly or indirectly as a 166 * callback from GLib. Also no mutexes may be currently locked while 167 * calling g_thread_init(). 168 * Note 169 * g_thread_init() changes the way in which GTimer measures 170 * elapsed time. As a consequence, timers that are running while 171 * g_thread_init() is called may report unreliable times. 172 * Calling g_thread_init() multiple times is allowed (since version 173 * 2.24), but nothing happens except for the first call. If the 174 * argument is non-NULL on such a call a warning will be printed, but 175 * otherwise the argument is ignored. 176 * If no thread system is available and vtable is NULL or if not all 177 * elements of vtable are non-NULL, then g_thread_init() will abort. 178 * Note 179 * To use g_thread_init() in your program, you have to link with 180 * the libraries that the command pkg-config --libs 181 * gthread-2.0 outputs. This is not the case for all the 182 * other thread related functions of GLib. Those can be used without 183 * having to link with the thread libraries. 184 * Params: 185 * vtable = a function table of type GThreadFunctions, that provides 186 * the entry points to the thread system to be used. 187 */ 188 public static void init(GThreadFunctions* vtable) 189 { 190 // void g_thread_init (GThreadFunctions *vtable); 191 g_thread_init(vtable); 192 } 193 194 /** 195 * This function returns TRUE if the thread system is initialized, and 196 * FALSE if it is not. 197 * Note 198 * This function is actually a macro. Apart from taking the 199 * address of it you can however use it as if it was a 200 * function. 201 * Returns: TRUE, if the thread system is initialized. 202 */ 203 public static int supported() 204 { 205 // gboolean g_thread_supported (); 206 return g_thread_supported(); 207 } 208 209 /** 210 * Indicates if g_thread_init() has been called. 211 * Since 2.20 212 * Returns: TRUE if threads have been initialized. 213 */ 214 public static int getInitialized() 215 { 216 // gboolean g_thread_get_initialized (void); 217 return g_thread_get_initialized(); 218 } 219 220 /** 221 * This function creates a new thread with the default priority. 222 * If joinable is TRUE, you can wait for this threads termination 223 * calling g_thread_join(). Otherwise the thread will just disappear 224 * when it terminates. 225 * The new thread executes the function func with the argument data. 226 * If the thread was created successfully, it is returned. 227 * error can be NULL to ignore errors, or non-NULL to report errors. 228 * The error is set, if and only if the function returns NULL. 229 * Params: 230 * func = a function to execute in the new thread. 231 * data = an argument to supply to the new thread. 232 * joinable = should this thread be joinable? 233 * Returns: the new GThread on success. 234 * Throws: GException on failure. 235 */ 236 public static Thread create(GThreadFunc func, void* data, int joinable) 237 { 238 // GThread * g_thread_create (GThreadFunc func, gpointer data, gboolean joinable, GError **error); 239 GError* err = null; 240 241 auto p = g_thread_create(func, data, joinable, &err); 242 243 if (err !is null) 244 { 245 throw new GException( new ErrorG(err) ); 246 } 247 248 249 if(p is null) 250 { 251 return null; 252 } 253 254 return new Thread(cast(GThread*) p); 255 } 256 257 /** 258 * This function creates a new thread with the priority priority. If 259 * the underlying thread implementation supports it, the thread gets a 260 * stack size of stack_size or the default value for the current 261 * platform, if stack_size is 0. 262 * If joinable is TRUE, you can wait for this threads termination 263 * calling g_thread_join(). Otherwise the thread will just disappear 264 * when it terminates. If bound is TRUE, this thread will be 265 * scheduled in the system scope, otherwise the implementation is free 266 * to do scheduling in the process scope. The first variant is more 267 * expensive resource-wise, but generally faster. On some systems (e.g. 268 * Linux) all threads are bound. 269 * The new thread executes the function func with the argument data. 270 * If the thread was created successfully, it is returned. 271 * error can be NULL to ignore errors, or non-NULL to report errors. 272 * The error is set, if and only if the function returns NULL. 273 * Note 274 * It is not guaranteed that threads with different priorities 275 * really behave accordingly. On some systems (e.g. Linux) there are no 276 * thread priorities. On other systems (e.g. Solaris) there doesn't 277 * seem to be different scheduling for different priorities. All in all 278 * try to avoid being dependent on priorities. Use 279 * G_THREAD_PRIORITY_NORMAL here as a default. 280 * Note 281 * Only use g_thread_create_full() if you really can't use 282 * g_thread_create() instead. g_thread_create() does not take 283 * stack_size, bound, and priority as arguments, as they should only 284 * be used in cases in which it is unavoidable. 285 * Params: 286 * func = a function to execute in the new thread. 287 * data = an argument to supply to the new thread. 288 * stackSize = a stack size for the new thread. 289 * joinable = should this thread be joinable? 290 * bound = should this thread be bound to a system thread? 291 * priority = a priority for the thread. 292 * Returns: the new GThread on success. 293 * Throws: GException on failure. 294 */ 295 public static Thread createFull(GThreadFunc func, void* data, gulong stackSize, int joinable, int bound, GThreadPriority priority) 296 { 297 // GThread * g_thread_create_full (GThreadFunc func, gpointer data, gulong stack_size, gboolean joinable, gboolean bound, GThreadPriority priority, GError **error); 298 GError* err = null; 299 300 auto p = g_thread_create_full(func, data, stackSize, joinable, bound, priority, &err); 301 302 if (err !is null) 303 { 304 throw new GException( new ErrorG(err) ); 305 } 306 307 308 if(p is null) 309 { 310 return null; 311 } 312 313 return new Thread(cast(GThread*) p); 314 } 315 316 /** 317 * This functions returns the GThread corresponding to the calling 318 * thread. 319 * Returns: the current thread. 320 */ 321 public static Thread self() 322 { 323 // GThread * g_thread_self (void); 324 auto p = g_thread_self(); 325 326 if(p is null) 327 { 328 return null; 329 } 330 331 return new Thread(cast(GThread*) p); 332 } 333 334 /** 335 * Waits until thread finishes, i.e. the function func, as given to 336 * g_thread_create(), returns or g_thread_exit() is called by thread. 337 * All resources of thread including the GThread struct are released. 338 * thread must have been created with joinable=TRUE in 339 * g_thread_create(). The value returned by func or given to 340 * g_thread_exit() by thread is returned by this function. 341 * Returns: the return value of the thread. 342 */ 343 public void* join() 344 { 345 // gpointer g_thread_join (GThread *thread); 346 return g_thread_join(gThread); 347 } 348 349 /** 350 * Changes the priority of thread to priority. 351 * Note 352 * It is not guaranteed that threads with different 353 * priorities really behave accordingly. On some systems (e.g. Linux) 354 * there are no thread priorities. On other systems (e.g. Solaris) there 355 * doesn't seem to be different scheduling for different priorities. All 356 * in all try to avoid being dependent on priorities. 357 * Params: 358 * priority = a new priority for thread. 359 */ 360 public void setPriority(GThreadPriority priority) 361 { 362 // void g_thread_set_priority (GThread *thread, GThreadPriority priority); 363 g_thread_set_priority(gThread, priority); 364 } 365 366 /** 367 * Gives way to other threads waiting to be scheduled. 368 * This function is often used as a method to make busy wait less evil. 369 * But in most cases you will encounter, there are better methods to do 370 * that. So in general you shouldn't use this function. 371 */ 372 public static void yield() 373 { 374 // void g_thread_yield (); 375 g_thread_yield(); 376 } 377 378 /** 379 * Exits the current thread. If another thread is waiting for that 380 * thread using g_thread_join() and the current thread is joinable, the 381 * waiting thread will be woken up and get retval as the return value 382 * of g_thread_join(). If the current thread is not joinable, retval 383 * is ignored. Calling 384 * $(DDOC_COMMENT example) 385 * is equivalent to returning retval from the function func, as given 386 * to g_thread_create(). 387 * Note 388 * Never call g_thread_exit() from within a thread of a 389 * GThreadPool, as that will mess up the bookkeeping and lead to funny 390 * and unwanted results. 391 * Params: 392 * retval = the return value of this thread. 393 */ 394 public static void exit(void* retval) 395 { 396 // void g_thread_exit (gpointer retval); 397 g_thread_exit(retval); 398 } 399 400 /** 401 * Call thread_func on all existing GThread structures. Note that 402 * threads may decide to exit while thread_func is running, so 403 * without intimate knowledge about the lifetime of foreign threads, 404 * thread_func shouldn't access the GThread* pointer passed in as 405 * first argument. However, thread_func will not be called for threads 406 * which are known to have exited already. 407 * Due to thread lifetime checks, this function has an execution complexity 408 * which is quadratic in the number of existing threads. 409 * Since 2.10 410 * Params: 411 * threadFunc = function to call for all GThread structures 412 * userData = second argument to thread_func 413 */ 414 public static void foreac(GFunc threadFunc, void* userData) 415 { 416 // void g_thread_foreach (GFunc thread_func, gpointer user_data); 417 g_thread_foreach(threadFunc, userData); 418 } 419 420 /** 421 * Function to be called when starting a critical initialization 422 * section. The argument value_location must point to a static 423 * 0-initialized variable that will be set to a value other than 0 at 424 * the end of the initialization section. In combination with 425 * g_once_init_leave() and the unique address value_location, it can 426 * be ensured that an initialization section will be executed only once 427 * during a program's life time, and that concurrent threads are 428 * blocked until initialization completed. To be used in constructs 429 * Since 2.14 430 * Params: 431 * valueLocation = location of a static initializable variable 432 * containing 0. 433 * Returns: TRUE if the initialization section should be entered, FALSE and blocks otherwise 434 */ 435 public static int onceInitEnter(out gsize valueLocation) 436 { 437 // gboolean g_once_init_enter (volatile gsize *value_location); 438 return g_once_init_enter(&valueLocation); 439 } 440 441 /** 442 * Counterpart to g_once_init_enter(). Expects a location of a static 443 * 0-initialized initialization variable, and an initialization value 444 * other than 0. Sets the variable to the initialization value, and 445 * releases concurrent threads blocking in g_once_init_enter() on this 446 * initialization variable. 447 * Since 2.14 448 * Params: 449 * valueLocation = location of a static initializable variable 450 * containing 0. 451 * initializationValue = new non-0 value for *value_location. 452 */ 453 public static void onceInitLeave(out gsize valueLocation, gsize initializationValue) 454 { 455 // void g_once_init_leave (volatile gsize *value_location, gsize initialization_value); 456 g_once_init_leave(&valueLocation, initializationValue); 457 } 458 459 /** 460 * Sets the indicated lock_bit in address. If the bit is already 461 * set, this call will block until g_bit_unlock() unsets the 462 * corresponding bit. 463 * Attempting to lock on two different bits within the same integer is 464 * not supported and will very probably cause deadlocks. 465 * The value of the bit that is set is (1u << bit). If bit is not 466 * between 0 and 31 then the result is undefined. 467 * This function accesses address atomically. All other accesses to 468 * address must be atomic in order for this function to work 469 * reliably. 470 * Since 2.24 471 * Params: 472 * address = a pointer to an integer 473 * lockBit = a bit value between 0 and 31 474 */ 475 public static void bitLock(ref int address, int lockBit) 476 { 477 // void g_bit_lock (volatile gint *address, gint lock_bit); 478 g_bit_lock(&address, lockBit); 479 } 480 481 /** 482 * Sets the indicated lock_bit in address, returning TRUE if 483 * successful. If the bit is already set, returns FALSE immediately. 484 * Attempting to lock on two different bits within the same integer is 485 * not supported. 486 * The value of the bit that is set is (1u << bit). If bit is not 487 * between 0 and 31 then the result is undefined. 488 * This function accesses address atomically. All other accesses to 489 * address must be atomic in order for this function to work 490 * reliably. 491 * Since 2.24 492 * Params: 493 * address = a pointer to an integer 494 * lockBit = a bit value between 0 and 31 495 * Returns: TRUE if the lock was acquired 496 */ 497 public static int bitTrylock(ref int address, int lockBit) 498 { 499 // gboolean g_bit_trylock (volatile gint *address, gint lock_bit); 500 return g_bit_trylock(&address, lockBit); 501 } 502 503 /** 504 * Clears the indicated lock_bit in address. If another thread is 505 * currently blocked in g_bit_lock() on this same bit then it will be 506 * woken up. 507 * This function accesses address atomically. All other accesses to 508 * address must be atomic in order for this function to work 509 * reliably. 510 * Since 2.24 511 * Params: 512 * address = a pointer to an integer 513 * lockBit = a bit value between 0 and 31 514 */ 515 public static void bitUnlock(ref int address, int lockBit) 516 { 517 // void g_bit_unlock (volatile gint *address, gint lock_bit); 518 g_bit_unlock(&address, lockBit); 519 } 520 }