24 #include <baseapp/thread_manager.h>
25 #include <core/threading/thread.h>
26 #include <core/threading/mutex_locker.h>
27 #include <core/threading/wait_condition.h>
28 #include <core/threading/thread_initializer.h>
29 #include <core/threading/thread_finalizer.h>
30 #include <core/exceptions/software.h>
31 #include <core/exceptions/system.h>
33 #include <aspect/blocked_timing.h>
60 ThreadManager::ThreadManagerAspectCollector::ThreadManagerAspectCollector(ThreadManager *parent_manager)
62 __parent_manager = parent_manager;
67 ThreadManager::ThreadManagerAspectCollector::add(ThreadList &tl)
69 BlockedTimingAspect *timed_thread;
71 for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) {
72 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(*i)) != NULL ) {
73 throw IllegalArgumentException(
"ThreadProducerAspect may not add threads with BlockedTimingAspect");
77 __parent_manager->add_maybelocked(tl,
false);
82 ThreadManager::ThreadManagerAspectCollector::add(Thread *t)
84 BlockedTimingAspect *timed_thread;
86 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(t)) != NULL ) {
87 throw IllegalArgumentException(
"ThreadProducerAspect may not add threads with BlockedTimingAspect");
90 __parent_manager->add_maybelocked(t,
false);
95 ThreadManager::ThreadManagerAspectCollector::remove(ThreadList &tl)
97 BlockedTimingAspect *timed_thread;
99 for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) {
100 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(*i)) != NULL ) {
101 throw IllegalArgumentException(
"ThreadProducerAspect may not remove threads with BlockedTimingAspect");
105 __parent_manager->remove_maybelocked(tl,
false);
110 ThreadManager::ThreadManagerAspectCollector::remove(Thread *t)
112 BlockedTimingAspect *timed_thread;
114 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(t)) != NULL ) {
115 throw IllegalArgumentException(
"ThreadProducerAspect may not remove threads with BlockedTimingAspect");
118 __parent_manager->remove_maybelocked(t,
false);
125 throw AccessViolationException(
"ThreadManagerAspect threads may not force removal of threads");
129 ThreadManager::ThreadManagerAspectCollector::force_remove(
fawkes::Thread *t)
131 throw AccessViolationException(
"ThreadManagerAspect threads may not force removal of threads");
139 ThreadManager::ThreadManager()
141 __initializer = NULL;
145 __interrupt_timed_thread_wait =
false;
146 __aspect_collector =
new ThreadManagerAspectCollector(
this);
158 __initializer = NULL;
162 __interrupt_timed_thread_wait =
false;
163 __aspect_collector =
new ThreadManagerAspectCollector(
this);
164 set_inifin(initializer, finalizer);
169 ThreadManager::~ThreadManager()
173 for (__tit = __threads.begin(); __tit != __threads.end(); ++__tit) {
174 __tit->second.force_stop(__finalizer);
176 __untimed_threads.force_stop(__finalizer);
179 delete __waitcond_timedthreads;
180 delete __aspect_collector;
192 __initializer = initializer;
193 __finalizer = finalizer;
205 ThreadManager::internal_remove_thread(
Thread *t)
209 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(t)) != NULL ) {
212 if ( __threads.find(hook) != __threads.end() ) {
213 __threads[hook].remove_locked(t);
214 if (__threads[hook].empty()) __threads.erase(hook);
217 __untimed_threads.remove_locked(t);
230 ThreadManager::internal_add_thread(Thread *t)
232 BlockedTimingAspect *timed_thread;
233 if ( (timed_thread = dynamic_cast<BlockedTimingAspect *>(t)) != NULL ) {
236 if ( __threads.find(hook) == __threads.end() ) {
237 __threads[hook].set_name(
"ThreadManagerList Hook %i", hook);
238 __threads[hook].set_maintain_barrier(
true);
240 __threads[hook].push_back_locked(t);
242 __waitcond_timedthreads->wake_all();
244 __untimed_threads.push_back_locked(t);
261 ThreadManager::add_maybelocked(ThreadList &tl,
bool lock)
263 if ( ! (__initializer && __finalizer) ) {
264 throw NullPointerException(
"ThreadManager: initializer/finalizer not set");
268 throw Exception(
"Not accepting new threads from list that is not fresh, "
269 "list '%s' already sealed", tl.name());
276 tl.init(__initializer, __finalizer);
277 }
catch (Exception &e) {
286 MutexLocker locker(__threads.mutex(), lock);
287 for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) {
288 internal_add_thread(*i);
306 ThreadManager::add_maybelocked(Thread *thread,
bool lock)
308 if ( thread == NULL ) {
309 throw NullPointerException(
"FawkesThreadMananger: cannot add NULL as thread");
312 if ( ! (__initializer && __finalizer) ) {
313 throw NullPointerException(
"ThreadManager: initializer/finalizer not set");
317 __initializer->init(thread);
318 }
catch (CannotInitializeThreadException &e) {
319 e.append(
"Adding thread in ThreadManager failed");
324 MutexLocker locker(__threads.mutex(), lock);
325 internal_add_thread(thread);
344 ThreadManager::remove_maybelocked(ThreadList &tl,
bool lock)
346 if ( ! (__initializer && __finalizer) ) {
347 throw NullPointerException(
"ThreadManager: initializer/finalizer not set");
351 if ( ! tl.sealed() ) {
352 throw ThreadListNotSealedException(
"(ThreadManager) Cannot remove unsealed thread "
353 "list. Not accepting unsealed list '%s' for removal",
358 MutexLocker locker(__threads.mutex(), lock);
361 if ( ! tl.prepare_finalize(__finalizer) ) {
362 tl.cancel_finalize();
364 throw CannotFinalizeThreadException(
"One or more threads in list '%s' cannot be "
365 "finalized", tl.name());
367 }
catch (CannotFinalizeThreadException &e) {
370 }
catch (Exception &e) {
372 e.append(
"One or more threads in list '%s' cannot be finalized", tl.name());
373 throw CannotFinalizeThreadException(e);
378 tl.finalize(__finalizer);
379 }
catch (Exception &e) {
384 for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) {
385 internal_remove_thread(*i);
405 ThreadManager::remove_maybelocked(Thread *thread,
bool lock)
407 if ( thread == NULL )
return;
409 if ( ! (__initializer && __finalizer) ) {
410 throw NullPointerException(
"ThreadManager: initializer/finalizer not set");
413 MutexLocker locker(__threads.mutex(), lock);
415 if ( ! thread->prepare_finalize() ) {
416 thread->cancel_finalize();
417 throw CannotFinalizeThreadException(
"Thread '%s'cannot be finalized", thread->name());
419 }
catch (CannotFinalizeThreadException &e) {
420 e.append(
"ThreadManager cannot stop thread '%s'", thread->name());
421 thread->cancel_finalize();
427 __finalizer->finalize(thread);
430 internal_remove_thread(thread);
461 __threads.mutex()->stopby();
464 for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) {
465 internal_remove_thread(*i);
500 if (__finalizer) __finalizer->finalize(thread);
503 internal_remove_thread(thread);
509 unsigned int timeout_usec)
513 unsigned int timeout_sec = 0;
514 if (timeout_usec >= 1000000) {
515 timeout_sec = timeout_usec / 1000000;
516 timeout_usec -= timeout_sec * 1000000;
520 if ( __threads.find(hook) != __threads.end() ) {
521 __threads[hook].wakeup_and_wait(timeout_sec, timeout_usec * 1000);
531 if ( __threads.find(hook) != __threads.end() ) {
533 __threads[hook].wakeup(barrier);
535 __threads[hook].wakeup();
537 if ( __threads[hook].size() == 0 ) {
538 __threads.erase(hook);
545 ThreadManager::try_recover(std::list<std::string> &recovered_threads)
548 for (__tit = __threads.begin(); __tit != __threads.end(); ++__tit) {
549 __tit->second.try_recover(recovered_threads);
556 ThreadManager::timed_threads_exist()
558 return (__threads.size() > 0);
563 ThreadManager::wait_for_timed_threads()
565 __interrupt_timed_thread_wait =
false;
566 __waitcond_timedthreads->wait();
567 if ( __interrupt_timed_thread_wait ) {
568 __interrupt_timed_thread_wait =
false;
574 ThreadManager::interrupt_timed_thread_wait()
576 __interrupt_timed_thread_wait =
true;
577 __waitcond_timedthreads->wake_all();
586 ThreadManager::aspect_collector()
const
588 return __aspect_collector;