24 #include <core/exceptions/software.h>
25 #include <core/exceptions/system.h>
26 #include <core/threading/barrier.h>
27 #include <core/threading/interruptible_barrier.h>
28 #include <core/threading/mutex.h>
29 #include <core/threading/mutex_locker.h>
30 #include <core/threading/thread.h>
31 #include <core/threading/thread_list.h>
54 : Exception(
"ThreadList is sealed")
56 append(
"Operation '%s' is not allowed on a sealed thread list", operation);
94 name_ = strdup(tlname);
109 name_ = strdup(tlname);
114 if (maintain_barrier)
123 name_ = strdup(tl.name_);
124 sealed_ = tl.sealed_;
127 if (tl.wnw_barrier_ != NULL)
135 delete finalize_mutex_;
147 name_ = strdup(tl.name_);
148 sealed_ = tl.sealed_;
149 finalize_mutex_ =
new Mutex();
151 if (tl.wnw_barrier_ != NULL)
163 for (iterator i = begin(); i != end(); ++i) {
175 for (iterator i = begin(); i != end(); ++i) {
188 for (iterator i = begin(); i != end(); ++i) {
189 (*i)->wakeup(barrier);
201 Exception * exc = NULL;
202 unsigned int count = 1;
203 for (iterator i = begin(); i != end(); ++i) {
204 if (!(*i)->flagged_bad()) {
206 (*i)->wakeup(barrier);
222 if (count != barrier->count()) {
223 throw Exception(
"ThreadList(%s)::wakeup(): barrier has count (%u) different "
224 "from number of unflagged threads (%u)",
244 throw NullPointerException(
"ThreadList::wakeup_and_wait() can only be called if "
245 "barrier is maintained");
252 }
catch (Exception &e) {
255 if (!wnw_barrier_->
wait(timeout_sec, timeout_nanosec)) {
257 RefPtr<ThreadList> passed_threads = wnw_barrier_->
passed_threads();
259 for (iterator i = begin(); i != end(); ++i) {
260 if ((*i)->flagged_bad()) {
265 for (iterator j = passed_threads->begin(); j != passed_threads->end(); ++j) {
272 bad_threads.push_back(*i);
277 wnw_bad_barriers_.push_back(make_pair(wnw_barrier_, bad_threads));
284 if (bad_threads.size() > 1) {
285 s =
"Multiple threads did not finish in time, flagging as bad: ";
286 for (iterator i = bad_threads.begin(); i != bad_threads.end(); ++i) {
287 s += std::string((*i)->name()) +
" ";
289 }
else if (bad_threads.size() == 0) {
290 s =
"Timeout happened, but no bad threads recorded.";
292 throw Exception(
"Thread %s did not finish in time (max %f), flagging as bad",
293 bad_threads.front()->name(),
294 (float)timeout_sec + (
float)timeout_nanosec / 1000000000.);
296 throw Exception(
"%s", s.c_str());
310 throw Exception(
"InterruptibleBarrier cannot be destroyed "
311 "when there still are threads in the wait() function");
315 if (maintain_barrier)
331 bool changed =
false;
332 wnw_bbit_ = wnw_bad_barriers_.begin();
333 while (wnw_bbit_ != wnw_bad_barriers_.end()) {
334 iterator i = wnw_bbit_->second.begin();
335 while (i != wnw_bbit_->second.end()) {
336 if ((*i)->cancelled()) {
338 i = wnw_bbit_->second.erase(i);
340 }
else if ((*i)->waiting()) {
342 recovered_threads.push_back((*i)->name());
345 i = wnw_bbit_->second.erase(i);
351 if (wnw_bbit_->second.empty() && wnw_bbit_->first->no_threads_in_wait()) {
352 delete wnw_bbit_->first;
353 wnw_bbit_ = wnw_bad_barriers_.erase(wnw_bbit_);
374 ThreadList::init(ThreadInitializer *initializer, ThreadFinalizer *finalizer)
376 CannotInitializeThreadException cite;
379 for (ThreadList::iterator i = begin(); i != end(); ++i) {
381 #ifndef DEBUG_THREAD_INIT
384 initializer->init(*i);
385 #ifndef DEBUG_THREAD_INIT
387 cite.append(
"Initialized failed to initialize thread '%s'", (*i)->name());
396 #ifndef DEBUG_THREAD_INIT
400 initialized_threads.push_back(*i);
401 #ifndef DEBUG_THREAD_INIT
402 }
catch (CannotInitializeThreadException &e) {
403 notify_of_failed_init();
404 cite.append(
"Initializing thread '%s' in list '%s' failed", (*i)->name(), name_);
406 finalizer->finalize(*i);
409 }
catch (Exception &e) {
410 notify_of_failed_init();
412 cite.append(
"Could not initialize thread '%s' (ThreadList %s)", (*i)->name(),
name());
413 finalizer->finalize(*i);
416 }
catch (std::exception &e) {
417 notify_of_failed_init();
418 cite.append(
"Caught std::exception: %s", e.what());
419 cite.append(
"Could not initialize thread '%s' (ThreadList %s)", (*i)->name(),
name());
420 finalizer->finalize(*i);
424 notify_of_failed_init();
425 cite.append(
"Could not initialize thread '%s' (ThreadList %s)", (*i)->name(),
name());
426 cite.append(
"Unknown exception caught");
427 finalizer->finalize(*i);
435 initialized_threads.finalize(finalizer);
449 for (iterator i = begin(); i != end(); ++i) {
474 for (iterator i = begin(); i != end(); ++i) {
499 for (iterator i = begin(); i != end(); ++i) {
513 for (reverse_iterator i = rbegin(); i != rend(); ++i) {
534 MutexLocker
lock(finalize_mutex_);
536 bool can_finalize =
true;
538 bool threw_exception =
false;
539 for (reverse_iterator i = rbegin(); i != rend(); ++i) {
544 if (!finalizer->prepare_finalize(*i)) {
545 can_finalize =
false;
547 if (!(*i)->prepare_finalize()) {
548 can_finalize =
false;
550 }
catch (CannotFinalizeThreadException &e) {
551 cfte.append(
"Thread '%s' threw an exception while preparing finalization of "
552 "ThreadList '%s' (IGNORED)",
556 threw_exception =
true;
557 }
catch (Exception &e) {
558 cfte.append(
"Thread '%s' threw a generic exception while preparing finalization of "
559 "ThreadList '%s' (IGNORED)",
563 threw_exception =
true;
566 if (threw_exception) {
583 Exception me(
"One or more threads failed to finalize");
584 for (reverse_iterator i = rbegin(); i != rend(); ++i) {
589 me.append(
"AspectIniFin called Thread[%s]::finalize() which failed", (*i)->name());
591 }
catch (Exception &e) {
593 me.append(
"AspectIniFin called Thread[%s]::finalize() which failed", (*i)->name());
597 me.append(
"Thread[%s]::finalize() threw unsupported exception", (*i)->name());
600 finalizer->finalize(*i);
601 }
catch (CannotFinalizeThreadException &e) {
603 me.append(
"Could not finalize thread '%s' in list '%s'", (*i)->name(), name_);
617 MutexLocker
lock(finalize_mutex_);
619 for (reverse_iterator i = rbegin(); i != rend(); ++i) {
620 (*i)->cancel_finalize();
636 for (i = begin(); i != end(); ++i) {
637 (*i)->set_prepfin_hold(hold);
639 }
catch (Exception &e) {
642 for (iterator j = begin(); j != i; ++j) {
643 (*j)->set_prepfin_hold(
false);
657 bool caught_exception =
false;
658 Exception exc(
"Forced thread finalization failed");
663 caught_exception =
true;
668 }
catch (Exception &e) {
669 caught_exception =
true;
674 }
catch (Exception &e) {
675 caught_exception =
true;
679 if (caught_exception) {
703 va_start(va, format);
706 if (vasprintf(&tmpname, format, va) != -1) {
888 ThreadList::update_barrier()
890 unsigned int num = 1;
891 for (iterator i = begin(); i != end(); ++i) {
892 if (!(*i)->flagged_bad())
900 wnw_bad_barriers_.push_back(make_pair(wnw_barrier_, empty_list));
902 wnw_barrier_ =
new InterruptibleBarrier(num);
907 ThreadList::notify_of_failed_init()
909 for (ThreadList::iterator i = begin(); i != end(); ++i) {
910 (*i)->notify_of_failed_init();