/** Wakeup all threads in list and have them wait for the barrier. * This method wakes up all thread without aquiring the lock first. * This method must only be used if the thread list is locked otherwise! * @param barrier Barrier to wait for after loop */ void ThreadList::wakeup_unlocked(Barrier *barrier) { Exception *exc = NULL; unsigned int count = 1; for (iterator i = begin(); i != end(); ++i) { if ( ! (*i)->flagged_bad() ) { try { (*i)->wakeup(barrier); } catch (Exception &e) { if (! exc) { exc = new Exception(e); } else { exc->append(e); } } ++count; } } if (exc) { Exception te(*exc); delete exc; throw te; } if (count != barrier->count()) { throw Exception("ThreadList(%s)::wakeup(): barrier has count (%u) different " "from number of unflagged threads (%u)", __name, barrier->count(), count); } }
void Exception::append(const Exception &another, size_t startDepth) throw() { Exception base; if (this == &another) { base.append(another, startDepth); append(base, 0); return; } size_t baseEntryCount = 0; if (!isEmpty()) { assert(base.isEmpty()); base.append(*this, 0); baseEntryCount = 1 + base.maxDepth_; clear(); } size_t subEntryCount = baseEntryCount + (another.maxDepth_ - startDepth); if (subEntryCount > 0) { subEntries_ = static_cast<Entry*>(allocate(sizeof(Entry) * subEntryCount)); if (subEntries_ == NULL) { subEntryCount = 0; } } maxDepth_ = subEntryCount; for (size_t i = 0; i <= subEntryCount; i++) { Entry &dest = (i > 0 ? subEntries_[i - 1] : topEntry_); const Entry *src; if (i < baseEntryCount) { src = base.getEntryAt(i); } else { src = another.getEntryAt(startDepth + (i - baseEntryCount)); } setEntry(dest, *src); } fillWhat(); }
/** Constructor. * @param config Fawkes configuration */ BlackBoardLoggerPlugin::BlackBoardLoggerPlugin(Configuration *config) : Plugin(config) { std::set<std::string> ifaces; std::string prefix = "/fawkes/bblogger/"; std::string replay_prefix = "/fawkes/bblogreplay/"; std::string scenario = ""; try { scenario = config->get_string((prefix + "scenario").c_str()); } catch (Exception &e) { e.append("No scenario defined, configure %sscenario", prefix.c_str()); throw; } /* bool generate_replay_config = false; try { generate_replay_config = config->get_bool((prefix + "generate_replay_config").c_str()); } catch (Exception &e) {} // ignored, use default set above */ std::string scenario_prefix = prefix + scenario + "/"; std::string ifaces_prefix = scenario_prefix + "interfaces/"; std::string logdir = LOGDIR; bool buffering = true; bool flushing = false; try { logdir = config->get_string((scenario_prefix + "logdir").c_str()); } catch (Exception &e) { /* ignored, use default set above */ } try { buffering = config->get_bool((scenario_prefix + "buffering").c_str()); } catch (Exception &e) { /* ignored, use default set above */ } try { flushing = config->get_bool((scenario_prefix + "flushing").c_str()); } catch (Exception &e) { /* ignored, use default set above */ } struct stat s; int err = stat(logdir.c_str(), &s); if (err != 0) { char buf[1024]; Exception se ("Cannot access logdir %s (%s)", logdir.c_str(), strerror_r(errno, buf, 1024)); if (mkdir(logdir.c_str(), 0755) != 0) { se.append("Failed to create log directory (%s)", strerror_r(errno, buf, 1024)); throw se; } } else if ( ! S_ISDIR(s.st_mode) ) { throw Exception("Logdir path %s is not a directory", logdir.c_str()); } // We do not have the framework clock available at this point, but for the start // time of the log we are only interested in the system time anyway Time start; char date[21]; Time now; struct tm *tmp = localtime(&(now.get_timeval()->tv_sec)); strftime(date, 21, "%F-%H-%M-%S", tmp); std::string replay_cfg_prefix = replay_prefix + scenario + "-" + date + "/logs/"; Configuration::ValueIterator *i = config->search(ifaces_prefix.c_str()); while (i->next()) { std::string iface_name = std::string(i->path()).substr(ifaces_prefix.length()); iface_name = iface_name.substr(0, iface_name.find("/")); //printf("Adding sync thread for peer %s\n", peer.c_str()); BBLoggerThread *log_thread = new BBLoggerThread(i->get_string().c_str(), logdir.c_str(), buffering, flushing, scenario.c_str(), &start); std::string filename = log_thread->get_filename(); config->set_string((replay_cfg_prefix + iface_name + "/file").c_str(), filename); thread_list.push_back(log_thread); } delete i; if ( thread_list.empty() ) { throw Exception("No interfaces configured for logging, aborting"); } BBLoggerThread *bblt = dynamic_cast<BBLoggerThread *>(thread_list.front()); bblt->set_threadlist(thread_list); }