Fawkes API  Fawkes Development Version
thread.cpp
1 
2 /***************************************************************************
3  * thread.cpp - implementation of threads, based on pthreads
4  *
5  * Created: Thu Sep 14 13:26:39 2006
6  * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/threading/thread.h>
25 #include <core/threading/mutex.h>
26 #include <core/threading/mutex_locker.h>
27 #include <core/threading/barrier.h>
28 #include <core/threading/wait_condition.h>
29 #include <core/threading/read_write_lock.h>
30 #include <core/threading/thread_finalizer.h>
31 #include <core/threading/thread_notification_listener.h>
32 #include <core/exceptions/software.h>
33 #include <core/exceptions/system.h>
34 #include <core/utils/lock_list.h>
35 
36 #if defined(__gnu_linux__) && ! defined(_GNU_SOURCE)
37 // to get pthread_setname_np
38 # define _GNU_SOURCE
39 #endif
40 #include <pthread.h>
41 #include <climits>
42 #include <unistd.h>
43 #include <cstring>
44 #include <cstdlib>
45 #include <cerrno>
46 #include <csignal>
47 #include <cstdio>
48 
49 namespace fawkes {
50 
51 /** @def forever
52  * Shortcut for "while (1)".
53  * @relates Thread
54  */
55 
56 /** @class Thread <core/threading/thread.h>
57  * Thread class encapsulation of pthreads.
58  * This is the base class for all threads in Fawkes. Derive this class for
59  * your thread. Note that you have to set a meaningful name, as this name
60  * is necessary for easier debugging and it is used for internal messaging
61  * via the BlackBoard. Make sure that your name is unique throughout the
62  * software. Using the class name with an additional modifier if it is instantiated
63  * multiple times is a good bet.
64  *
65  * The thread can operate in two modes. The loop can either run continuously
66  * without a brake, or it can wait for an explicit wakeup after each loop.
67  * Waiting for an explicit wakeup is the default since this is the common use
68  * case in Fawkes and also it is less risky, the developer will easier see that
69  * his thread does not do anything then fixing that the thread takes all CPU time.
70  *
71  * Special care has been taken to allow for proper initialization and
72  * finalization. The special behavior of this routines can only be guaranteed
73  * if the threads are managed properly, which is the case if we speak of the
74  * Fawkes thread manager. This applies for the following paragraphs.
75  *
76  * The thread provides an init() routine which may be implemented
77  * and is called just before the thread is started. If you make use of aspects
78  * this is the first time when you can make use of aspects. These aspects
79  * are not initialized in the constructor. init() is called just after the
80  * aspect initialization. This is also the last chance to stop the thread
81  * from being executed if you detect an error. If init() throws any exception
82  * then the thread is never started.
83  *
84  * The methods prepare_finalize(), finalize() and cancel_finalize() are meant
85  * to be used for finalization. First prepare_finalize() is called to prepare
86  * finalization. At this stage the thread can veto and prevent finalization
87  * from happening. For this prepare_finalize_user() has to be implemented
88  * with the proper check, and maybe special actions that are needed to
89  * prepare finalization (which may or may not happen independent from the
90  * result of just this thread, see method description). Afterwards finalize()
91  * may be called (independent of the prepare_finalize() result, see method
92  * description). If finalize() is not executed the thread is notified with
93  * cancel_finalize(). Before finalize() is called the thread is stopped.
94  *
95  * The intialization and finalization procedures may be executed deferred and
96  * concurrent to the running thread itself. The thread is only started however
97  * it init() finished successfully.
98  *
99  * The call to prepare_finalize() is mutual exclusive with a concurrently running
100  * loop() by default. This means that if the loop() blocks waiting for some event
101  * prepare_finalize() will hang until this event happens. This can be prevented
102  * with set_prepfin_conc_loop() which allows to set that prepare_finalize() and
103  * loop() may be executed concurrently.
104  *
105  * After prepare_finalize() has been run the thread implementation will stop the
106  * loop() from being executed. However, the thread will still run, for example it will
107  * wait for wakeup. This way it can be ensured that other threads will continue
108  * to run even this thread is currently not running. An exception is the
109  * ThreadList. For this Thread provides special synchronization features by
110  * which it is possible to stop a thread in the very same loop iteration. That
111  * means that if you have two threads that are woken up at the same time and
112  * maybe even synchronize among each other it is guaranteed that both threads
113  * will finish the running loop and never enter the next loop.
114  * Before finalize() is called the thread shall be stopped (cancelled and joined).
115  *
116  * Because the finalization is done deferred and concurrent put all lengthy
117  * finalization routines in finalize() and avoid this in the destructor, since
118  * a long running destructor will harm the overall performance while with the
119  * surrounding framework a long-running finalize() is acceptable.
120  *
121  * Please read the Fawkes documentation about guarantees (FawkesGuarantees in
122  * the wiki) for information about the given guarantees. Several of these
123  * guarantees are met if Thread is used in conjunction with ThreadList and the
124  * guarantees have been specifically designed for painless plugin development.
125  *
126  * @ingroup Threading
127  * @ingroup FCL
128  * @see Aspects
129  * @see loop()
130  * @see run()
131  * @see ThreadList
132  * @see example_barrier.cpp
133  * @see example_mutex_count.cpp
134  * @see example_rwlock.cpp
135  * @see example_waitcond_serialize.cpp
136  *
137  * @author Tim Niemueller
138  */
139 
140 /** @var bool Thread::finalize_prepared
141  * True if prepare_finalize() has been called and was not stopped with a
142  * cancel_finalize(), false otherwise.
143  * This can also be used in finalize() to detect whether prepare_finalize() was
144  * run or not.
145  */
146 
147 /** @var Mutex * Thread::loop_mutex
148  * Mutex that is used to protect a call to loop().
149  * This mutex is locked just before loop() is called and unlocked right after it
150  * has finished. So you can use this lock in your derivate to make sure that a
151  * method does not run while the loop runs.
152  * For example assume that we have a method set_parameter(int x). This method may
153  * only be called if loop() is not running or unpredictable results will occur.
154  * To do this you could write the method as
155  * @code
156  * MyThread::set_parameter(int x)
157  * {
158  * loopinterrupt_antistarve_mutex->lock();
159  * loop_mutex->lock();
160  * // do what you need to do...
161  * loop_mutex->unlock();
162  * loopinterrupt_antistarve_mutex->unlock();
163  * }
164  * @endcode
165  * See documentation for loopinterrupt_antistarve_mutex why you need to use two
166  * mutexes here.
167  */
168 
169 /** @var Mutex * Thread::loopinterrupt_antistarve_mutex
170  * Mutex to avoid starvation when trying to lock loop_mutex.
171  * If you want to interrupt the main loop only locking loop_mutex is not enough,
172  * as this might make your try to lock it starve if the loop is running too fast
173  * (for example on a continuous thread). Because of this you always need to
174  * lock both mutexes. The anti-starve mutex will only be visited shortly and thus
175  * allows you to lock it easily. This will then block the thread from trying to
176  * lock the loop_mutex. See loop_mutex for an example.
177  */
178 
179 /** @fn const char * Thread::name() const
180  * Get name of thread.
181  * This name is mainly used for debugging purposes. Give it a descriptive
182  * name. Is nothing is given the raw class name is used.
183  * @return thread name
184  */
185 
186 
187 /** We need not initialize this one timely by ourselves thus we do not use Mutex */
188 pthread_mutex_t Thread::__thread_key_mutex = PTHREAD_MUTEX_INITIALIZER;
189 
190 
191 /** Key used to store a reference to the thread object as thread specific data. */
192 pthread_key_t Thread::THREAD_KEY = PTHREAD_KEYS_MAX;
193 
194 #define MAIN_THREAD_NAME "__MainThread__"
195 
196 /** Standard thread flag: "thread is bad" */
197 const unsigned int Thread::FLAG_BAD = 0x00000001;
198 
199 /** Constructor.
200  * This constructor is protected so that Thread cannot be instantiated. This
201  * constructor initalizes a few internal variables. Uses continuous
202  * operation mode.
203  * @param name thread name, used for debugging, see Thread::name()
204  */
205 Thread::Thread(const char *name)
206 {
207  __constructor(name, OPMODE_CONTINUOUS);
208 }
209 
210 
211 /** Constructor.
212  * This constructor is protected so that Thread cannot be instantiated. This
213  * constructor initalizes a few internal variables.
214  * @param name thread name, used for debugging, see Thread::name()
215  * @param op_mode Operation mode, see Thread::OpMode
216  */
217 Thread::Thread(const char *name, OpMode op_mode)
218 {
219  __constructor(name, op_mode);
220 }
221 
222 
223 /** Constructor.
224  * This constructor is protected so that Thread cannot be instantiated. This
225  * constructor initalizes a few internal variables.
226  * This is used to create a Thread wrapper instance for an existing thread.
227  * Use internally only!
228  * @param name thread name, used for debugging, see Thread::name()
229  * @param id thread ID of running thread
230  */
231 Thread::Thread(const char *name, pthread_t id)
232 {
233  __constructor(name, OPMODE_CONTINUOUS);
234  __thread_id = id;
235 }
236 
237 
238 /** Initialize.
239  * Kind of the base constructor.
240  * @param name name of thread
241  * @param op_mode operation mode
242  */
243 void
244 Thread::__constructor(const char *name, OpMode op_mode)
245 {
246  init_thread_key();
247 
248  __prepfin_conc_loop = false;
249  __coalesce_wakeups = false;
250  __op_mode = op_mode;
251  __name = strdup(name);
252  __notification_listeners = new LockList<ThreadNotificationListener *>();
253 
254  if ( __op_mode == OPMODE_WAITFORWAKEUP ) {
255  __sleep_mutex = new Mutex();
256  __sleep_condition = new WaitCondition(__sleep_mutex);
257  __waiting_for_wakeup = true;
258  } else {
259  __sleep_condition = NULL;
260  __sleep_mutex = NULL;
261  __waiting_for_wakeup = false;
262  }
263 
264  __thread_id = 0;
265  __flags = 0;
266  __barrier = NULL;
267  __started = false;
268  __cancelled = false;
269  __delete_on_exit = false;
270  __prepfin_hold = false;
271  __pending_wakeups = 0;
272 
273  loop_mutex = new Mutex();
274  finalize_prepared = false;
275 
276  __loop_done = true;
277  __loop_done_mutex = new Mutex();
278  __loop_done_waitcond = new WaitCondition(__loop_done_mutex);
279 
281  __prepfin_hold_mutex = new Mutex();
282  __prepfin_hold_waitcond = new WaitCondition(__prepfin_hold_mutex);
283  __startup_barrier = new Barrier(2);
284 }
285 
286 
287 /** Virtual destructor. */
289 {
290  __loop_done_waitcond->wake_all();
291  yield();
292 
293  delete __sleep_condition;
294  delete __sleep_mutex;
295  delete loop_mutex;
296  free(__name);
297  delete __notification_listeners;
299  delete __startup_barrier;
300  delete __prepfin_hold_mutex;
301  delete __prepfin_hold_waitcond;
302  delete __loop_done_waitcond;
303  delete __loop_done_mutex;
304 }
305 
306 
307 
308 /** Copy constructor is NOT supported.
309  * Using this constructor will cause havoc and chaos. It's only here
310  * as private constructor to hide it! Therefore if you ever use it
311  * internally it will always throw an exception.
312  * @param t thread to copy.
313  * @exception Exception Always thrown
314  */
315 Thread::Thread(const Thread &t)
316 {
317  throw Exception("You may not use copy constructor of class Thread");
318 }
319 
320 
321 /** Assignment is not allowed.
322  * You may not assign one thread to another.
323  * @param t thread to assign
324  */
325 Thread &
326 Thread::operator=(const Thread &t)
327 {
328  throw Exception("You may not use assignment operator of class Thread");
329 }
330 
331 
332 /** Initialize the thread.
333  * This method is meant to be used in conjunction with aspects. Some parts
334  * of the initialization may only happen after some aspect of the thread has
335  * been initialized. Implement the init method with these actions. It is
336  * guaranteed to be called just after all aspects have been initialized
337  * and only once in the lifetime of the thread.
338  * Throw an exception if any problem occurs and the thread should not run.
339  *
340  * Just because your init() routine suceeds and everything looks fine for
341  * this thread does not automatically imply that it will run. If it belongs
342  * to a group of threads in a ThreadList and any of the other threads fail
343  * to initialize then no thread from this group is run and thus this thread
344  * will never run. In that situation finalize() is called for this very
345  * instance, prepare_finalize() however is not called.
346  *
347  * @see Aspects
348  */
349 void
351 {
352 }
353 
354 
355 /** Prepare finalization.
356  * Check if finalization at this point is possible and if so execute the
357  * steps necessary to prepare for finalization. You also have to make sure
358  * that this state of being able to finalize does not change until either
359  * finalize() or cancel_finalize() is called.
360  *
361  * This method may return false, which means that at this point the thread
362  * cannot be stopped safely. This might be due to a critical internal
363  * condition that may hurt hardware if turned of right now. In this case
364  * a logger should be used to log the reason for the failure. The check is
365  * implemented in prepare_finalize_user(), which the user has to implement
366  * if he needs special treatment.
367  *
368  * Even if the finalization is said to be unsafe and false is returned, the
369  * caller may still decide to finalize this thread, for example if all
370  * threads are shut down on application exit. So you may not rely on the
371  * fact that the thread is not stopped if you return false.
372  *
373  * You may not override this method.
374  *
375  * It is guaranteed that this method is only called for a running thread.
376  *
377  * @return true if the thread can be stopped and destroyed safely, false if
378  * it has to stay alive
379  * @see finalize()
380  * @see cancel_finalize()
381  */
382 bool
384 {
385  if ( ! __started ) {
386  throw CannotFinalizeThreadException("Thread has not been started");
387  }
388  if ( finalize_prepared ) {
389  throw CannotFinalizeThreadException("prepare_finalize() has already been called");
390  }
391  __prepfin_hold_mutex->lock();
392  while (__prepfin_hold) {
393  __prepfin_hold_waitcond->wait();
394  }
395  if (! __prepfin_conc_loop) {
397  loop_mutex->lock();
398  }
399  finalize_prepared = true;
400  bool prepared = prepare_finalize_user();
401  if (! __prepfin_conc_loop) {
402  loop_mutex->unlock();
404  }
405  __prepfin_hold_mutex->unlock();
406  return prepared;
407 }
408 
409 
410 /** Prepare finalization user implementation.
411  * This method is called by prepare_finalize(). If there can ever be a
412  * situation where it is not safe to turn of a thread at some point in
413  * time then implement this method to determine these unsafe states.
414  *
415  * An example that comes to my mind is our Katana arm. If you turn it off
416  * it looses all power and collapses back upon itself. This may damage the
417  * arm if it is not in a safe position. In this situation this method would
418  * return false to indicate this problem.
419  *
420  * It is up to the user to decide if this should be taken for an implied
421  * signal to get in such a safe state, if this is possible at all.
422  *
423  * This feature should be used rarely as it can have tremendous implications
424  * on the performance and experience of the whole software. In any case your
425  * implementation should somehow inform the user of the problem that caused
426  * the finalization to fail. If you are using aspect use the LoggerAspect and
427  * log the reason.
428  *
429  * The default implementation always allows finalization.
430  * @return true, if the thread can be finalized, false otherwise.
431  */
432 bool
434 {
435  return true;
436 }
437 
438 
439 /** Finalize the thread.
440  * This method is executed just before the thread is canceled and destroyed.
441  * It is always preceeded by a call to prepare_finalize(). If this is not
442  * the case this is a failure. The condition can be checked with
443  * the boolean variable finalize_prepared.
444  *
445  * This method is meant to be used in conjunction with aspects and to cover
446  * thread inter-dependencies. This routine MUST bring the thread into a safe
447  * state such that it may be canceled and destroyed afterwards. If there is
448  * any reason that this cannot happen make your prepare_finalize() reports so.
449  *
450  * This method is called by the thread manager just before the thread is
451  * being cancelled. Here you can do whatever steps are necessary just before
452  * the thread is cancelled. Note that you thread is still running and might
453  * be in the middle of a loop, so it is not a good place to give up on all
454  * resources used. Mind segmentation faults that could happen. Protect the
455  * area with a mutex that you lock at the beginning of your loop and free
456  * in the end, and that you lock at the beginning of finalize and then never
457  * unlock. Also not that the finalization may be canceled afterwards. The
458  * next thing that happens is that either the thread is canceled and destroyed
459  * or that the finalization is canceled and the thread has to run again.
460  *
461  * Finalize is called on a thread just before it is deleted. It is guaranteed
462  * to be called on a fully initialized thread (if no exception is thrown in
463  * init()) (this guarantee holds in the Fawkes framework).
464  *
465  * The default implementation does nothing besides throwing an exception if
466  * prepare_finalize() has not been called.
467  *
468  * @exception Exception thrown if prepare_finalize() has not been called.
469  * @see prepare_finalize()
470  * @see cancel_finalize()
471  */
472 void
474 {
475 }
476 
477 
478 /** Cancel finalization.
479  * This means that something has happened (for example another thread from
480  * the same plugin) has indicated that it can not be finalized. In that case
481  * also this thread has to continue to run and the finalization is canceled.
482  * The thread is expected to run after the finalization has been canceled as
483  * if the finalization was never tried.
484  *
485  * This is only called on a running thread after prepare_finalization() has
486  * been called.
487  *
488  * @see prepare_finalize()
489  * @see finalize()
490  */
491 void
493 {
494  if ( ! __started ) {
495  throw CannotFinalizeThreadException("Cannot cancel finalize, thread has not been started");
496  }
497  loop_mutex->lock();
498  finalize_prepared = false;
499  loop_mutex->unlock();
500 }
501 
502 
503 /** Call this method to start the thread.
504  * This method has to be called after the thread has been instantiated and
505  * initialized to start it. To meet the Fawkes guarantees you this may only
506  * be called if the initialization of the thread has been successful.
507  * @param wait if true this method will block until the thread is really
508  * started, otherwise it will only initiate the startup and return immediately
509  */
510 void
511 Thread::start(bool wait)
512 {
513  int err;
514  if (__started) {
515  throw Exception("You cannot start the same thread twice!");
516  }
517 
518  __cancelled = false;
519  __detached = false;
520  __started = true;
521  __wait = wait;
522 
523  if ( (err = pthread_create(&__thread_id, NULL, Thread::entry, this)) != 0) {
524  // An error occured
525  throw Exception("Could not start thread", err);
526  }
527 #if defined(_GNU_SOURCE) && defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12) || __GLIBC__ > 2)
528  char tmpname[16];
529  strncpy(tmpname, __name, 15);
530  tmpname[15] = 0;
531  pthread_setname_np(__thread_id, tmpname);
532 #endif
533 
534  if (__wait) __startup_barrier->wait();
535 }
536 
537 
538 void
539 Thread::lock_sleep_mutex()
540 {
541  if (__sleep_mutex) {
542  __sleep_mutex->lock();
543  }
544 }
545 
546 
547 /** Entry point for the thread.
548  * This is an utility method that acts as an entry point to the thread.
549  * It is called automatically when you start the thread and will call run()
550  * @param pthis a pointer to the instance that triggered the run of this method
551  */
552 /* static */ void *
553 Thread::entry(void *pthis)
554 {
555  Thread *t = (Thread *)pthis;
556 
557  // Can be used for easier debugging in gdb, need to make this accessible
558  // printf("Thread %s (%lu) started\n", t->name(), t->thread_id());
559 
560  // Set thread instance as TSD
561  set_tsd_thread_instance(t);
562 
563  // lock sleep mutex, needed such that thread waits for initial wakeup
564  t->lock_sleep_mutex();
565 
566  // Notify listeners that this thread started
567  t->notify_of_startup();
568 
569  // Thread is started now, thread that called start() will continue
570  if (t->__wait) t->__startup_barrier->wait();
571 
572  // Run thread
573  t->loop_mutex->lock();
574  t->once();
575  t->loop_mutex->unlock();
576  t->run();
577 
578  if ( t->__detached ) {
579  // mark as stopped if detached since the thread will be deleted
580  // after entry() is done
581  t->__started = false;
582  }
583 
584  // have no useful exit value
585  return NULL;
586 }
587 
588 
589 /** Exit the thread.
590  * You may call this from within your run() method to exit the thread.
591  * @see run()
592  */
593 void
595 {
596  if ( __delete_on_exit ) {
597  delete this;
598  }
599 
600  __waiting_for_wakeup = false;
601  __cancelled = true;
602  pthread_exit(NULL);
603 }
604 
605 
606 /** Join the thread.
607  * This waites for the thread to exit.
608  */
609 void
611 {
612  if ( __started ) {
613  void *dont_care;
614  pthread_join(__thread_id, &dont_care);
615  __started = false;
616 
617  if ( __sleep_mutex != NULL ) {
618  // We HAVE to release this sleep mutex under any circumstances, so we try
619  // to lock it (locking a locked mutex or unlocking and unlocked mutex are undefined)
620  // and then unlock it. This is for example necessary if a thread is cancelled, and
621  // then set_opmode() is called, this would lead to a deadlock if the thread was
622  // cancelled while waiting for the sleep lock (which is very likely)
623  __sleep_mutex->try_lock();
624  __sleep_mutex->unlock();
625  }
626 
627  // Force unlock of these mutexes, otherwise the same bad things as for the sleep
628  // mutex above could happen!
629  loop_mutex->try_lock();
630  loop_mutex->unlock();
631  }
632 }
633 
634 
635 /** Detach the thread.
636  * Memory claimed by the thread will be automatically freed after the
637  * thread exits. You can no longer join this thread.
638  */
639 void
641 {
642  __detached = true;
643  pthread_detach(__thread_id);
644 }
645 
646 
647 /** Cancel a thread.
648  * Use this to cancel the thread.
649  */
650 void
652 {
653  if ( __started && ! __cancelled ) {
654  if ( pthread_cancel(__thread_id) == 0 ) {
655  __waiting_for_wakeup = false;
656  __cancelled = true;
657  }
658  }
659 }
660 
661 
662 /** Send signal to a thread.
663  * Not that sending an unhandled signal might kill the whole process, not just the
664  * thread!
665  * @param sig signal to send.
666  */
667 void
668 Thread::kill(int sig)
669 {
670  pthread_kill(__thread_id, sig);
671 }
672 
673 
674 /** Get operation mode.
675  * @return opmode of thread.
676  */
679 {
680  return __op_mode;
681 }
682 
683 
684 /** Set operation mode.
685  * This can be done at any time and the thread will from the next cycle on
686  * run in the new mode.
687  * @param op_mode new operation mode
688  */
689 void
691 {
692  if ( __started ) {
693  throw Exception("Cannot set thread opmode while running");
694  }
695 
696  if ( (__op_mode == OPMODE_WAITFORWAKEUP) &&
697  (op_mode == OPMODE_CONTINUOUS) ) {
698  __op_mode = OPMODE_CONTINUOUS;
699  delete __sleep_condition;
700  delete __sleep_mutex;
701  __sleep_condition = NULL;
702  __sleep_mutex = NULL;
703  } else if ( (__op_mode == OPMODE_CONTINUOUS) &&
704  (op_mode == OPMODE_WAITFORWAKEUP) ) {
705  __sleep_mutex = new Mutex();
706  __sleep_condition = new WaitCondition(__sleep_mutex);
707  __op_mode = OPMODE_WAITFORWAKEUP;
708  }
709 }
710 
711 
712 /** Set concurrent execution of prepare_finalize() and loop().
713  * Usually calls to prepare_finalize() and a running loop() are mutually exclusive.
714  * The prepare_finalize() call will wait for the current loop() run to finish before
715  * calling the user implementation. If you have a thread that blocks in its loop for
716  * example in a blocking system call this would lead to a dead-lock if no condition
717  * that makes the loop finish occurs. For this reason this method has been added.
718  * If you set this to true then prepare_finalize() can be executed concurrent to
719  * a running loop() call. If this is critical for parts of loop() you have to
720  * protect the critical sections by yourself. Use this sparsely and be sure you really
721  * know what you are doing. This method is necessary in some situations and powerful
722  * if used wisely. By default a thread will enforce mutual exclusion.
723  * @param concurrent true to allow concurrent execution of prepare_finalize() and loop(),
724  * false to enforce mutual exclusion (the latter being the default)
725  */
726 void
728 {
729  __prepfin_conc_loop = concurrent;
730 }
731 
732 
733 /** Set wakeup coalescing.
734  * The standard behavior of multiple calls to wakeup() (before the thread actually
735  * got woken up, for instance because a loop iteration was still running) is to
736  * execute one iteration for each wakeup. When setting coalescing, multiple calls
737  * will only cause a single execution of the loop.
738  * @param coalesce true to coalesce wakeups, false to keep the original behavior
739  */
740 void
742 {
743  if ( __op_mode == OPMODE_CONTINUOUS ) {
744  // nothing is using the value, just write it
745  __coalesce_wakeups = coalesce;
746  } else {
747  // protect usage for calls to wakeup()
748  MutexLocker lock(__sleep_mutex);
749  __coalesce_wakeups = coalesce;
750  }
751 }
752 
753 
754 /** Set name of thread.
755  * If you want a more descriptive thread name you can do so by calling this method
756  * in your thread's constructor, and only in the constructor.
757  * Use parameters similar to printf().
758  * @param format format string
759  */
760 void
761 Thread::set_name(const char *format, ...)
762 {
763  va_list va;
764  va_start(va, format);
765  char *old_name = __name;
766  if (vasprintf(&__name, format, va) == -1) {
767  __name = old_name;
768  throw OutOfMemoryException("Could not set new thread name for '%s'", __name);
769  } else {
770  free(old_name);
771  }
772  va_end(va);
773 #if defined(_GNU_SOURCE) && defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12) || __GLIBC__ > 2)
774  if (__thread_id) {
775  char tmpname[16];
776  strncpy(tmpname, __name, 15);
777  tmpname[15] = 0;
778  pthread_setname_np(__thread_id, tmpname);
779  }
780 #endif
781 }
782 
783 
784 /** Hold prepare_finalize().
785  * In some situations you have to hold the finalization of a thread up to a certain
786  * safe point. With set_prepfin_hold() you can do this. If you set \p hold to true
787  * then a call to \c prepare_finalize() will block until \c set_prepfin_hold(false)
788  * is called.
789  * @param hold true to hold next call to \c prepare_finalize(), false to release it
790  * @exception Exception thrown if \c prepare_finalize() has already been called before
791  * trying to set \p hold to true.
792  */
793 void
795 {
796  __prepfin_hold_mutex->lock();
797  if ( hold && finalize_prepared ) {
798  __prepfin_hold_mutex->unlock();
799  throw Exception("Thread(%s)::set_prepfin_hold: prepare_finalize() has "
800  "been called already()", __name);
801  }
802  __prepfin_hold = hold;
803  if ( ! hold ) {
804  __prepfin_hold_waitcond->wake_all();
805  }
806  __prepfin_hold_mutex->unlock();
807 }
808 
809 
810 /** Get ID of thread.
811  * @return thread ID
812  */
813 pthread_t
815 {
816  return __thread_id;
817 }
818 
819 
820 /** Check if thread has been started.
821  * @return true if thread has been started, false otherwise
822  */
823 bool
825 {
826  return __started;
827 }
828 
829 
830 /** Check if thread has been cancelled.
831  * @return true if the thread has been cancelled, false otherwise
832  */
833 bool
835 {
836  return __cancelled;
837 }
838 
839 
840 /** Check if thread has been detached.
841  * @return true if the thread has been detached, false otherwise
842  */
843 bool
845 {
846  return __detached;
847 }
848 
849 
850 /** Check if the thread is running.
851  * A thread is running if it currently is busy in its loop() or once() method.
852  * @return true if the thread is running, false otherwise
853  */
854 bool
856 {
857  // loop_mutex is mutable and thus we can call the lock methods here
858  if (loop_mutex->try_lock()) {
859  loop_mutex->unlock();
860  return false;
861  } else {
862  return true;
863  }
864 }
865 
866 
867 /** Check if thread is currently waiting for wakeup.
868  * A continuous thread is never waiting for wakeup and thus will always return
869  * false. A wait-for-wakeup thread is waiting when it has passed the wakeup
870  * barrier (if supplied) and is now waiting for the next call to wakeup()
871  * to run again.
872  * @return true if the thread is waiting, false otherwise
873  */
874 bool
876 {
877  if (__op_mode != OPMODE_WAITFORWAKEUP) {
878  return false;
879  } else {
880  MutexLocker lock(__sleep_mutex);
881  return __waiting_for_wakeup;
882  }
883 }
884 
885 /** Set cancellation point.
886  * Tests if the thread has been canceled and if so exits the thread.
887  */
888 void
890 {
891  pthread_testcancel();
892 }
893 
894 
895 /** Yield the processor to another thread or process.
896  * This will suspend the execution of the current thread in favor of other
897  * threads. The thread will then be re-scheduled for later execution.
898  * Use this method to make sure that other threads get a chance to get the CPU
899  * for example if your thread is waiting for results from other threads.
900  */
901 void
903 {
904 #ifdef __USE_GNU
905  pthread_yield();
906 #else
907  usleep(0);
908 #endif
909 }
910 
911 
912 /** Check if two threads are the same.
913  * @param thread Thread to compare this thread to.
914  * @return true, if the threads are equal, false otherwise.
915  */
916 bool
918 {
919  return ( pthread_equal(__thread_id, thread.__thread_id) != 0 );
920 }
921 
922 
923 /** Code to execute in the thread.
924  * Executes loop() in each cycle. This is the default implementation and if
925  * you need a more specific behaviour you can override this run() method and
926  * ignore loop().
927  * Although this method is declared virtual, it should not be overridden, other
928  * than with the following trivial snippet:
929  * @code
930  * protected: virtual void run() { Thread::run(); }
931  * @endcode
932  * The reason not to do other changes is that it contains complex house keeping
933  * code that the system relies on. The reason for still allowing the override is
934  * solely to make reading back traces in your debugger easier. Because now there
935  * the class name of the thread sub-class will appear in the back trace, while
936  * it would not otherwise.
937  */
938 void
940 {
941  if ( __op_mode == OPMODE_WAITFORWAKEUP ) {
942  // Wait for initial wakeup
943  // __sleep_mutex has been locked in entry() already!
944  while (__pending_wakeups == 0) {
945  __waiting_for_wakeup = true;
946  __sleep_condition->wait();
947  }
948  __pending_wakeups -= 1;
949  __sleep_mutex->unlock();
950  }
951 
952  forever {
953 
955 
956  loop_mutex->lock();
957  if ( ! finalize_prepared ) {
958  __loop_done = false;
959  loop();
960  }
961  loop_mutex->unlock();
962 
963  __loop_done_mutex->lock();
964  __loop_done = true;
965  __loop_done_mutex->unlock();
966  __loop_done_waitcond->wake_all();
967 
968  test_cancel();
969  if ( __op_mode == OPMODE_WAITFORWAKEUP ) {
970  if ( __barrier ) {
971  __sleep_mutex->lock();
972  Barrier *b = __barrier;
973  __barrier = NULL;
974  __sleep_mutex->unlock();
975 
976  b->wait();
977 
978  __sleep_mutex->lock();
979  } else {
980  __sleep_mutex->lock();
981  }
982 
983  while (__pending_wakeups == 0) {
984  __waiting_for_wakeup = true;
985  __sleep_condition->wait();
986  }
987  __pending_wakeups -= 1;
988  __sleep_mutex->unlock();
989  }
990  yield();
991  }
992 }
993 
994 
995 /** Wake up thread.
996  * If the thread is being used in wait for wakeup mode this will wake up the
997  * waiting thread.
998  */
999 void
1001 {
1002  if ( __op_mode == OPMODE_WAITFORWAKEUP ) {
1003  MutexLocker lock(__sleep_mutex);
1004 
1005  if ( __barrier ) {
1006  throw Exception("Thread(%s): wakeup() cannot be called if loop is running "
1007  "with barrier already", __name);
1008  }
1009 
1010  if (__coalesce_wakeups) __pending_wakeups = 1;
1011  else __pending_wakeups += 1;
1012  if (__waiting_for_wakeup) {
1013  // currently waiting
1014  __waiting_for_wakeup = false;
1015  __sleep_condition->wake_all();
1016  }
1017  }
1018 }
1019 
1020 
1021 /** Wake up thread and wait for barrier afterwards.
1022  * If the thread is being used in wait for wakeup mode this will wake up the
1023  * waiting thread. Additionally after the loop is finished
1024  * @param barrier barrier to wait for after loop
1025  */
1026 void
1028 {
1029  if ( __op_mode != OPMODE_WAITFORWAKEUP ) return;
1030 
1031  if ( barrier == NULL ) {
1032  throw NullPointerException("Thread(%s)::wakeup(): barrier must not be NULL", __name);
1033  }
1034 
1035  MutexLocker lock(__sleep_mutex);
1036  if ( ! __waiting_for_wakeup && __barrier) {
1037  throw Exception("Thread %s already running with barrier, cannot wakeup %i %p", __name,
1038  __waiting_for_wakeup, __barrier);
1039  }
1040 
1041  __pending_wakeups += 1;
1042  __barrier = barrier;
1043  if (__waiting_for_wakeup) {
1044  // currently waiting
1045  __waiting_for_wakeup = false;
1046  __sleep_condition->wake_all();
1047  }
1048 }
1049 
1050 
1051 /** Wait for the current loop iteration to finish. */
1052 void
1054 {
1055  __loop_done_mutex->lock();
1056  while (! __loop_done) {
1057  __loop_done_waitcond->wait();
1058  }
1059  __loop_done_mutex->unlock();
1060 }
1061 
1062 /** Code to execute in the thread.
1063  * Implement this method to hold the code you want to be executed continously.
1064  * If you do not implement this method, the default is that the thread will exit.
1065  * This is useful if you choose to only implement once().
1066  */
1067 void
1069 {
1070  if ( __delete_on_exit ) {
1071  delete this;
1072  }
1073  loop_mutex->unlock();
1074  pthread_exit(NULL);
1075 }
1076 
1077 
1078 /** Execute an action exactly once.
1079  * This code is executed once and only once right after the thread is started
1080  * before loop() is called.
1081  * This is useful if you want to implement an one-shot background job. Just implement
1082  * once() and leave loop() untouched. Start the thread and detach it and it will just
1083  * do its job and then die automatically. If you use set_delete_on_exit(true) even the
1084  * Thread instance will be automatically deleted.
1085  */
1086 void
1088 {
1089 }
1090 
1091 
1092 /** Set whether the thread should be deleted on exit.
1093  * If you set this to true the thread instance is deleted if the threads exits
1094  * (only on internal exits, not if you cancel the thread!).
1095  * This is particularly useful if you only implement once() and not loop().
1096  * @param del true to delete thread on exit, false otherwise
1097  */
1098 void
1100 {
1101  __delete_on_exit = del;
1102 }
1103 
1104 
1105 /** Check if wakeups are pending.
1106  * @return true if at least one more loop iteration has been queued (wakeup() has
1107  * been called), false otherwise
1108  */
1109 bool
1111 {
1112  MutexLocker lock(__sleep_mutex);
1113  return (__pending_wakeups > 0);
1114 }
1115 
1116 /** Set flag for the thread.
1117  * The first two bytes of the flags are reserved for custom usage from the outside
1118  * and they are never used internally. The last two bytes are used to indicate
1119  * internal states, like flagging a thread as bad (timing was not ok). Setting
1120  * the latter bits may have influence on the inner workings on the thread and
1121  * thus should only be done if you really know what you are doing.
1122  * @param flag flag to set
1123  * @see set_flags()
1124  */
1125 void
1126 Thread::set_flag(uint32_t flag)
1127 {
1128  __flags |= flag;
1129 }
1130 
1131 
1132 /** Unset flag.
1133  * Unsets a specified flag.
1134  * @param flag flag to unset
1135  * @see set_flag()
1136  */
1137 void
1138 Thread::unset_flag(uint32_t flag)
1139 {
1140  __flags &= 0xFFFFFFFF ^ flag;
1141 }
1142 
1143 
1144 /** Set all flags in one go.
1145  * @param flags flags
1146  */
1147 void
1148 Thread::set_flags(uint32_t flags)
1149 {
1150  __flags = flags;
1151 }
1152 
1153 
1154 /** Check if FLAG_BAD was set.
1155  * This is a convenience method to check if FLAG_BAD has been set.
1156  * @return true if flag is set, false otherwise
1157  */
1158 bool
1160 {
1161  return __flags & FLAG_BAD;
1162 }
1163 
1164 
1165 /** Add notification listener.
1166  * Add a notification listener for this thread.
1167  * @param notification_listener notification listener to add
1168  */
1169 void
1171 {
1172  __notification_listeners->push_back_locked(notification_listener);
1173 }
1174 
1175 
1176 /** Remove notification listener.
1177  * @param notification_listener notification listener to remove
1178  */
1179 void
1181 {
1182  __notification_listeners->remove_locked(notification_listener);
1183 }
1184 
1185 
1186 /** Notify of successful startup.
1187  * This method is called internally in entry().
1188  */
1189 void
1190 Thread::notify_of_startup()
1191 {
1192  __notification_listeners->lock();
1193  LockList<ThreadNotificationListener *>::iterator i = __notification_listeners->begin();
1194  while (i != __notification_listeners->end()) {
1195  if (! (*i)->thread_started(this)) {
1196  i = __notification_listeners->erase(i);
1197  } else {
1198  ++i;
1199  }
1200  }
1201  __notification_listeners->unlock();
1202 }
1203 
1204 
1205 /** Notify of failed init.
1206  * This method must be called if the initialization of the thread
1207  * failed, e.g. in a thread collector. Do not use it arbitrarily!
1208  */
1209 void
1211 {
1212  __notification_listeners->lock();
1213  LockList<ThreadNotificationListener *>::iterator i = __notification_listeners->begin();
1214  while (i != __notification_listeners->end()) {
1215  if ( ! (*i)->thread_init_failed(this) ) {
1216  i = __notification_listeners->erase(i);
1217  } else {
1218  ++i;
1219  }
1220  }
1221  __notification_listeners->unlock();
1222 }
1223 
1224 
1225 /** Intialize thread key.
1226  * For internal usage only.
1227  */
1228 void
1229 Thread::init_thread_key()
1230 {
1231  pthread_mutex_lock(&__thread_key_mutex);
1232  if ( THREAD_KEY == PTHREAD_KEYS_MAX ) {
1233  // Has not been initialized, do it!
1234  int err;
1235  if ( (err = pthread_key_create(&THREAD_KEY, NULL)) != 0 ) {
1236  if ( ENOMEM == err ) {
1237  throw OutOfMemoryException("Could not create key for thread "
1238  "specific data (reference to thread)");
1239  } else {
1240  throw Exception("Thread key for reference to thread could not be created", err);
1241  }
1242  }
1243  }
1244  pthread_mutex_unlock(&__thread_key_mutex);
1245 }
1246 
1247 
1248 /** Set thread instance in thread-specific data (TSD).
1249  * Use thread-specific data to store a reference to the Thread instance in the
1250  * pthread struct. Used by current_thread().
1251  * @param t thread to set specific data on
1252  */
1253 void
1254 Thread::set_tsd_thread_instance(Thread *t)
1255 {
1256  int err = 0;
1257  if ( (err = pthread_setspecific(THREAD_KEY, t)) != 0 ) {
1258  if ( ENOMEM == err ) {
1259  throw OutOfMemoryException("Could not set specific data (reference to thread)");
1260  } else {
1261  throw Exception("Could not set specific data (reference to thread), unknown reason");
1262  }
1263  }
1264 }
1265 
1266 
1267 /** Initialize Thread wrapper instance for main thread.
1268  * This will create an internal Thread instance such that it can be guaranteed that
1269  */
1270 void
1272 {
1273  init_thread_key();
1274  Thread *t = new Thread(MAIN_THREAD_NAME, pthread_self());
1275  set_tsd_thread_instance(t);
1276 }
1277 
1278 
1279 /** Destroy main thread wrapper instance.
1280  * This destroys the thread wrapper created with init_main(). Note that
1281  * this has to be called from the very same thread that init_main() was called
1282  * from, which should be the main thread (somewhere from main() on).
1283  */
1284 void
1286 {
1287  Thread *t = current_thread();
1288  if ( strcmp(t->name(), MAIN_THREAD_NAME) == 0 ) {
1289  delete t;
1290  } else {
1291  throw Exception("Main thread can only be destroyed in main thread");
1292  }
1293 }
1294 
1295 
1296 /** Get the ID of the currently running thread.
1297  * This will return the ID of the thread in which's context this method was
1298  * called.
1299  * @return ID of thread context
1300  */
1301 pthread_t
1303 {
1304  return pthread_self();
1305 }
1306 
1307 
1308 /** Get the Thread instance of the currently running thread.
1309  * This will return the Thread instance of the thread in which's context this method was
1310  * called.
1311  * Note that only if the main application ensures to call init_main() it can be guaranteed
1312  * that this value is not NULL.
1313  * @return Thread instance of the current thread
1314  * @exception Exception thrown if this method is called before either init_main() is
1315  * called or any one thread has been started.
1316  */
1317 Thread *
1319 {
1320  if ( THREAD_KEY == PTHREAD_KEYS_MAX ) {
1321  throw Exception("No thread has been initialized");
1322  }
1323  return (Thread *)pthread_getspecific(THREAD_KEY);
1324 }
1325 
1326 
1327 /** Similar to current_thread, but does never throw an exception.
1328  * This is a convenience method doing the same as current_thread(), but it never ever
1329  * throws an exception, rather it returns NULL in case of an error. This is necessary
1330  * if run from a C context.
1331  * @return Thread instance of the current thread
1332  */
1333 Thread *
1335 {
1336  if ( THREAD_KEY == PTHREAD_KEYS_MAX ) {
1337  return 0;
1338  }
1339  return (Thread *)pthread_getspecific(THREAD_KEY);
1340 }
1341 
1342 
1343 /** Set the cancel state of the current thread.
1344  * The cancel state can only be set on the current thread. Please also
1345  * consider the documentation for pthread_setcancelstate().
1346  * @param new_state new cancel state
1347  * @param old_state old cancel state
1348  */
1349 void
1351 {
1352  int oldstate = PTHREAD_CANCEL_ENABLE;
1353  int newstate = PTHREAD_CANCEL_ENABLE;
1354  if ( new_state == CANCEL_DISABLED ) {
1355  newstate = PTHREAD_CANCEL_DISABLE;
1356  }
1357 
1358  pthread_setcancelstate(newstate, &oldstate);
1359 
1360  if ( old_state != NULL ) {
1361  if ( oldstate == PTHREAD_CANCEL_DISABLE ) {
1362  *old_state = CANCEL_DISABLED;
1363  } else {
1364  *old_state = CANCEL_ENABLED;
1365  }
1366  }
1367 }
1368 
1369 
1370 } // end namespace fawkes
bool operator==(const Thread &thread)
Check if two threads are the same.
Definition: thread.cpp:917
Thread(const char *name)
Constructor.
Definition: thread.cpp:205
void add_notification_listener(ThreadNotificationListener *notification_listener)
Add notification listener.
Definition: thread.cpp:1170
Wait until a given condition holds.
virtual void once()
Execute an action exactly once.
Definition: thread.cpp:1087
void unset_flag(uint32_t flag)
Unset flag.
Definition: thread.cpp:1138
bool finalize_prepared
True if prepare_finalize() has been called and was not stopped with a cancel_finalize(), false otherwise.
Definition: thread.h:138
Fawkes library namespace.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
virtual void wait()
Wait for other threads.
Definition: barrier.cpp:157
void wake_all()
Wake up all waiting threads.
virtual ~Thread()
Virtual destructor.
Definition: thread.cpp:288
virtual void run()
Code to execute in the thread.
Definition: thread.cpp:939
OpMode
Thread operation mode.
Definition: thread.h:52
Mutex locking helper.
Definition: mutex_locker.h:33
bool running() const
Check if the thread is running.
Definition: thread.cpp:855
Thread notification listener interface.
void cancel_finalize()
Cancel finalization.
Definition: thread.cpp:492
bool flagged_bad() const
Check if FLAG_BAD was set.
Definition: thread.cpp:1159
bool wakeup_pending()
Check if wakeups are pending.
Definition: thread.cpp:1110
thread cannot be cancelled
Definition: thread.h:62
A NULL pointer was supplied where not allowed.
Definition: software.h:34
Thread class encapsulation of pthreads.
Definition: thread.h:42
bool waiting() const
Check if thread is currently waiting for wakeup.
Definition: thread.cpp:875
static void init_main()
Initialize Thread wrapper instance for main thread.
Definition: thread.cpp:1271
void set_prepfin_conc_loop(bool concurrent=true)
Set concurrent execution of prepare_finalize() and loop().
Definition: thread.cpp:727
Mutex * loop_mutex
Mutex that is used to protect a call to loop().
Definition: thread.h:139
virtual bool prepare_finalize_user()
Prepare finalization user implementation.
Definition: thread.cpp:433
static void set_cancel_state(CancelState new_state, CancelState *old_state=0)
Set the cancel state of the current thread.
Definition: thread.cpp:1350
static Thread * current_thread_noexc()
Similar to current_thread, but does never throw an exception.
Definition: thread.cpp:1334
bool cancelled() const
Check if thread has been cancelled.
Definition: thread.cpp:834
void wait_loop_done()
Wait for the current loop iteration to finish.
Definition: thread.cpp:1053
OpMode opmode() const
Get operation mode.
Definition: thread.cpp:678
Mutex * loopinterrupt_antistarve_mutex
Mutex to avoid starvation when trying to lock loop_mutex.
Definition: thread.h:140
void wakeup()
Wake up thread.
Definition: thread.cpp:1000
void set_name(const char *format,...)
Set name of thread.
Definition: thread.cpp:761
Base class for exceptions in Fawkes.
Definition: exception.h:36
static pthread_t current_thread_id()
Get the ID of the currently running thread.
Definition: thread.cpp:1302
static void destroy_main()
Destroy main thread wrapper instance.
Definition: thread.cpp:1285
virtual void finalize()
Finalize the thread.
Definition: thread.cpp:473
bool started() const
Check if thread has been started.
Definition: thread.cpp:824
List with a lock.
Definition: thread.h:40
bool prepare_finalize()
Prepare finalization.
Definition: thread.cpp:383
operate in continuous mode (default)
Definition: thread.h:53
void set_delete_on_exit(bool del)
Set whether the thread should be deleted on exit.
Definition: thread.cpp:1099
void set_opmode(OpMode op_mode)
Set operation mode.
Definition: thread.cpp:690
static Thread * current_thread()
Get the Thread instance of the currently running thread.
Definition: thread.cpp:1318
void remove_notification_listener(ThreadNotificationListener *notification_listener)
Remove notification listener.
Definition: thread.cpp:1180
const char * name() const
Get name of thread.
Definition: thread.h:95
void notify_of_failed_init()
Notify of failed init.
Definition: thread.cpp:1210
static const unsigned int FLAG_BAD
Standard thread flag: "thread is bad".
Definition: thread.h:65
void set_coalesce_wakeups(bool coalesce=true)
Set wakeup coalescing.
Definition: thread.cpp:741
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:120
void wait()
Wait for the condition forever.
void cancel()
Cancel a thread.
Definition: thread.cpp:651
void kill(int sig)
Send signal to a thread.
Definition: thread.cpp:668
void test_cancel()
Set cancellation point.
Definition: thread.cpp:889
bool detached() const
Check if thread has been detached.
Definition: thread.cpp:844
virtual void loop()
Code to execute in the thread.
Definition: thread.cpp:1068
void yield()
Yield the processor to another thread or process.
Definition: thread.cpp:902
pthread_t thread_id() const
Get ID of thread.
Definition: thread.cpp:814
Thread cannot be finalized.
void detach()
Detach the thread.
Definition: thread.cpp:640
void join()
Join the thread.
Definition: thread.cpp:610
void set_prepfin_hold(bool hold)
Hold prepare_finalize().
Definition: thread.cpp:794
void lock()
Lock this mutex.
Definition: mutex.cpp:89
cancellation is possible
Definition: thread.h:61
virtual void init()
Initialize the thread.
Definition: thread.cpp:350
void set_flag(uint32_t flag)
Set flag for the thread.
Definition: thread.cpp:1126
operate in wait-for-wakeup mode
Definition: thread.h:54
Mutex mutual exclusion lock.
Definition: mutex.h:32
void exit()
Exit the thread.
Definition: thread.cpp:594
void stopby()
Shortly stop by at the mutex.
Definition: mutex.cpp:155
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
Definition: barrier.h:32
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
void set_flags(uint32_t flags)
Set all flags in one go.
Definition: thread.cpp:1148
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:511
CancelState
Cancel state.
Definition: thread.h:60