Fawkes API
Fawkes Development Version
|
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>
56 append(
"Operation '%s' is not allowed on a sealed thread list", operation);
94 name_ = strdup(tlname);
96 finalize_mutex_ =
new Mutex();
109 name_ = strdup(tlname);
111 finalize_mutex_ =
new Mutex();
114 if (maintain_barrier)
123 name_ = strdup(tl.name_);
124 sealed_ = tl.sealed_;
125 finalize_mutex_ =
new Mutex();
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);
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)",
245 "barrier is maintained");
255 if (!wnw_barrier_->
wait(timeout_sec, timeout_nanosec)) {
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) {
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.);
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_);
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
401 #ifndef DEBUG_THREAD_INIT
403 notify_of_failed_init();
404 cite.
append(
"Initializing thread '%s' in list '%s' failed", (*i)->name(), name_);
410 notify_of_failed_init();
412 cite.
append(
"Could not initialize thread '%s' (ThreadList %s)", (*i)->name(),
name());
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());
424 notify_of_failed_init();
425 cite.
append(
"Could not initialize thread '%s' (ThreadList %s)", (*i)->name(),
name());
426 cite.
append(
"Unknown exception caught");
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) {
536 bool can_finalize =
true;
538 bool threw_exception =
false;
539 for (reverse_iterator i = rbegin(); i != rend(); ++i) {
545 can_finalize =
false;
547 if (!(*i)->prepare_finalize()) {
548 can_finalize =
false;
551 cfte.
append(
"Thread '%s' threw an exception while preparing finalization of "
552 "ThreadList '%s' (IGNORED)",
556 threw_exception =
true;
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());
593 me.
append(
"AspectIniFin called Thread[%s]::finalize() which failed", (*i)->name());
597 me.
append(
"Thread[%s]::finalize() threw unsupported exception", (*i)->name());
603 me.
append(
"Could not finalize thread '%s' in list '%s'", (*i)->name(), name_);
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);
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;
669 caught_exception =
true;
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();
bool sealed()
Check if list is sealed.
LockList< Type > & operator=(const LockList< Type > &ll)
Copy values from another LockList.
virtual void lock() const
Lock list.
void force_stop(ThreadFinalizer *finalizer)
Force stop of all threads.
void wakeup()
Wakeup all threads in list.
void clear()
Clear the list.
void append_va(const char *format, va_list va)
Append messages to the message list.
void set_name(const char *format,...)
Set name of thread.
void remove(Thread *thread)
Remove with lock protection.
Mutex mutual exclusion lock.
void set_maintain_barrier(bool maintain_barrier)
Set if this thread list should maintain a barrier.
bool wait(unsigned int timeout_sec, unsigned int timeout_nanosec)
Wait for other threads.
ThreadList::iterator erase(iterator pos)
Erase element at given position.
void push_back(Thread *thread)
Add thread to the end.
RefPtr<> is a reference-counting shared smartpointer.
ThreadListSealedException(const char *operation)
Constructor.
ThreadListNotSealedException(const char *format,...)
Constructor.
virtual void init(Thread *thread)=0
This method is called by the ThreadManager for each newly added Thread.
Thread list sealed exception.
Thread cannot be initialized.
void set_prepfin_hold(bool hold)
Set prepfin hold on all threads.
void append(const char *format,...)
Append messages to the message list.
void cancel()
Cancel threads.
RefPtr< Mutex > mutex() const
Get access to the internal mutex.
void push_front_locked(Thread *thread)
Add thread to the front with lock protection.
RefPtr< ThreadList > passed_threads()
Get a list of threads that passed the barrier.
const char * name()
Name of the thread list.
Fawkes library namespace.
ThreadList & operator=(const ThreadList &tl)
Assignment operator.
void finalize(ThreadFinalizer *finalizer)
Finalize Threads.
void pop_front()
Remove first element.
bool prepare_finalize(ThreadFinalizer *finalizer)
Prepare finalize.
bool no_threads_in_wait()
Checks if there are no more threads in the wait() function.
void remove_locked(Thread *thread)
Remove with lock protection.
Thread finalizer interface.
Thread class encapsulation of pthreads.
void pop_back()
Remove last element.
virtual void finalize(Thread *thread)=0
Finalize a thread.
unsigned int count()
Get number of threads this barrier will wait for.
A NULL pointer was supplied where not allowed.
void init(ThreadInitializer *initializer, ThreadFinalizer *finalizer)
Initialize threads.
System ran out of memory and desired operation could not be fulfilled.
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
Thread initializer interface.
Thread cannot be finalized.
void try_recover(std::list< std::string > &recovered_threads)
Check if any of the bad barriers recovered.
virtual bool prepare_finalize(Thread *thread)=0
Prepare finalization of a thread.
void start()
Start threads.
void push_front(Thread *thread)
Add thread to the front.
ThreadList(const char *tlname="")
Constructor.
void push_back_locked(Thread *thread)
Add thread to the end with lock protection.
void wakeup_unlocked()
Wakeup all threads in list.
static const unsigned int FLAG_BAD
Standard thread flag: "thread is bad".
void cancel_finalize()
Cancel finalization on all threads.
void seal()
Seal the list.
void wakeup_and_wait(unsigned int timeout_sec=0, unsigned int timeout_nanosec=0)
Wakeup threads and wait for them to finish.
Base class for exceptions in Fawkes.