inifin.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <aspect/inifin.h>
00025
00026 #include <core/threading/thread.h>
00027 #include <core/macros.h>
00028 #include <blackboard/blackboard.h>
00029 #include <aspect/blackboard.h>
00030 #include <aspect/blocked_timing.h>
00031 #include <aspect/configurable.h>
00032 #include <aspect/logging.h>
00033 #include <aspect/clock.h>
00034 #include <aspect/fawkes_network.h>
00035 #include <aspect/network.h>
00036 #include <aspect/thread_producer.h>
00037 #include <aspect/time_source.h>
00038 #include <aspect/mainloop.h>
00039 #include <aspect/mainloop/employer.h>
00040 #include <aspect/logger.h>
00041 #include <aspect/logger/employer.h>
00042 #include <aspect/plugin_director.h>
00043 #ifdef HAVE_FIREVISION
00044 #include <aspect/vision_master.h>
00045 #include <aspect/vision.h>
00046 #endif
00047
00048 namespace fawkes {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 AspectIniFin::AspectIniFin(BlackBoard *blackboard,
00068 ThreadCollector *collector,
00069 Configuration *config,
00070 Logger *logger,
00071 Clock *clock)
00072
00073 {
00074 __blackboard = blackboard;
00075 __thread_collector = collector;
00076 __config = config;
00077 __logger = logger;
00078 __clock = clock;
00079 __fnethub = NULL;
00080 __nnresolver = NULL;
00081 __service_publisher = NULL;
00082 __service_browser = NULL;
00083 __mainloop_employer = NULL;
00084 }
00085
00086
00087
00088 AspectIniFin::~AspectIniFin()
00089 {
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 void
00101 AspectIniFin::set_fnet_hub(FawkesNetworkHub *fnethub)
00102 {
00103 __fnethub = fnethub;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113 void
00114 AspectIniFin::set_mainloop_employer(MainLoopEmployer *employer)
00115 {
00116 __mainloop_employer = employer;
00117 }
00118
00119
00120
00121
00122
00123 void
00124 AspectIniFin::set_logger_employer(LoggerEmployer *employer)
00125 {
00126 __logger_employer = employer;
00127 }
00128
00129
00130
00131
00132
00133
00134 void
00135 AspectIniFin::set_blocked_timing_executor(BlockedTimingExecutor *btexec)
00136 {
00137 __btexec = btexec;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 void
00151 AspectIniFin::set_network_members(NetworkNameResolver *nnresolver,
00152 ServicePublisher *service_publisher,
00153 ServiceBrowser *service_browser)
00154 {
00155 __nnresolver = nnresolver;
00156 __service_publisher = service_publisher;
00157 __service_browser = service_browser;
00158 }
00159
00160
00161
00162
00163
00164 void
00165 AspectIniFin::set_plugin_manager(PluginManager *manager)
00166 {
00167 __plugin_manager = manager;
00168 }
00169
00170
00171
00172
00173
00174 void
00175 AspectIniFin::init(Thread *thread)
00176 {
00177
00178
00179 BlockedTimingAspect *blocked_timing_thread __unused;
00180 if ( (blocked_timing_thread = dynamic_cast<BlockedTimingAspect *>(thread)) != NULL ) {
00181 if ( thread->opmode() != Thread::OPMODE_WAITFORWAKEUP ) {
00182 throw CannotInitializeThreadException("Thread '%s' not in WAITFORWAKEUP mode "
00183 "(required for BlockedTimingAspect)",
00184 thread->name());
00185 }
00186 }
00187
00188 BlackBoardAspect *blackboard_thread;
00189 if ( (blackboard_thread = dynamic_cast<BlackBoardAspect *>(thread)) != NULL ) {
00190 blackboard_thread->init_BlackBoardAspect( __blackboard );
00191 }
00192
00193 ThreadProducerAspect *thread_producer_thread;
00194 if ( (thread_producer_thread = dynamic_cast<ThreadProducerAspect *>(thread)) != NULL ) {
00195 thread_producer_thread->init_ThreadProducerAspect( __thread_collector );
00196 }
00197
00198 ConfigurableAspect *configurable_thread;
00199 if ( (configurable_thread = dynamic_cast<ConfigurableAspect *>(thread)) != NULL ) {
00200 configurable_thread->init_ConfigurableAspect(__config);
00201 }
00202
00203 LoggingAspect *logging_thread;
00204 if ( (logging_thread = dynamic_cast<LoggingAspect *>(thread)) != NULL ) {
00205 logging_thread->init_LoggingAspect(__logger);
00206 }
00207
00208 ClockAspect *clock_thread;
00209 if ( (clock_thread = dynamic_cast<ClockAspect *>(thread)) != NULL ) {
00210 clock_thread->init_ClockAspect(__clock);
00211 }
00212
00213 PluginDirectorAspect *plugin_director_thread;
00214 if ( (plugin_director_thread = dynamic_cast<PluginDirectorAspect *>(thread)) != NULL ) {
00215 if ( thread->opmode() != Thread::OPMODE_CONTINUOUS ) {
00216 throw CannotInitializeThreadException("Thread '%s' not in CONTINUOUS mode "
00217 "(required for PluginDirectorAspect)",
00218 thread->name());
00219 }
00220 if ( __plugin_manager ) {
00221 plugin_director_thread->init_PluginDirectorAspect(__plugin_manager);
00222 } else {
00223 throw CannotInitializeThreadException("Thread '%s' has PluginDirectorAspect "
00224 "but no PluginManager has been set in "
00225 "AspectIniFin", thread->name());
00226 }
00227 }
00228
00229 FawkesNetworkAspect *fnet_thread;
00230 if ( (fnet_thread = dynamic_cast<FawkesNetworkAspect *>(thread)) != NULL ) {
00231 if ( __fnethub == NULL ) {
00232 throw CannotInitializeThreadException("Thread '%s' has FawkesNetworkAspect but no "
00233 "FawkesNetworkHub has been set in AspectIniFin",
00234 thread->name());
00235 }
00236 fnet_thread->init_FawkesNetworkAspect(__fnethub);
00237 }
00238
00239 #ifdef HAVE_FIREVISION
00240 VisionMasterAspect *vision_master_thread;
00241 if ( (vision_master_thread = dynamic_cast<VisionMasterAspect *>(thread)) != NULL ) {
00242 try {
00243 __vision_dependency.add(vision_master_thread);
00244 thread->add_notification_listener(this);
00245 } catch (DependencyViolationException &e) {
00246 CannotInitializeThreadException ce("Dependency violation for VisionProviderAspect "
00247 "detected");
00248 ce.append(e);
00249 throw ce;
00250 }
00251 }
00252
00253 VisionAspect *vision_thread;
00254 if ( (vision_thread = dynamic_cast<VisionAspect *>(thread)) != NULL ) {
00255 try {
00256 if ( (vision_thread->vision_thread_mode() == VisionAspect::CONTINUOUS) &&
00257 (thread->opmode() != Thread::OPMODE_CONTINUOUS) ) {
00258 throw CannotInitializeThreadException("Vision thread '%s' operates in continuous "
00259 "mode but thread does not", thread->name());
00260 }
00261 if ( (vision_thread->vision_thread_mode() == VisionAspect::CYCLIC) &&
00262 (thread->opmode() != Thread::OPMODE_WAITFORWAKEUP) ) {
00263 throw CannotInitializeThreadException("Vision thread '%s' operates in cyclic mode but"
00264 "thread does not operate in wait-for-wakeup "
00265 "mode.", thread->name());
00266 }
00267 __vision_dependency.add(vision_thread);
00268 vision_thread->init_VisionAspect( __vision_dependency.provider()->vision_master() );
00269 thread->add_notification_listener(this);
00270 } catch (DependencyViolationException &e) {
00271 CannotInitializeThreadException ce("Dependency violation for VisionAspect detected");
00272 ce.append(e);
00273 throw ce;
00274 }
00275 }
00276 #endif
00277
00278 NetworkAspect *net_thread;
00279 if ( (net_thread = dynamic_cast<NetworkAspect *>(thread)) != NULL ) {
00280 if ( (__nnresolver == NULL) || (__service_publisher == NULL) ||
00281 (__service_browser == NULL) ) {
00282 throw CannotInitializeThreadException("Thread has NetworkAspect but required data "
00283 "has not been set in AspectIniFin");
00284 }
00285 net_thread->init_NetworkAspect(__nnresolver, __service_publisher, __service_browser);
00286 }
00287
00288 TimeSourceAspect *timesource_thread;
00289 if ( (timesource_thread = dynamic_cast<TimeSourceAspect *>(thread)) != NULL ) {
00290 try {
00291 __timesource_uc.add(timesource_thread->get_timesource());
00292 __clock->register_ext_timesource(timesource_thread->get_timesource(),
00293 true);
00294 } catch (...) {
00295 throw CannotInitializeThreadException("Thread has TimeSourceAspect but there is "
00296 "already another time provider.");
00297 }
00298 }
00299
00300 MainLoopAspect *mainloop_thread;
00301 if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
00302 if (thread->opmode() != Thread::OPMODE_WAITFORWAKEUP) {
00303 throw CannotInitializeThreadException("MainLoopAspect thread must operate "
00304 "in wait-for-wakeup mode.");
00305
00306 }
00307 if ( __mainloop_employer == NULL ) {
00308 throw CannotInitializeThreadException("Thread has MainLoopAspect but no "
00309 "MainLoopEmployer has been set.");
00310 }
00311 if ( __btexec == NULL ) {
00312 throw CannotInitializeThreadException("Thread has MainLoopAspect but no "
00313 "BlockedTimingExecutor has been set.");
00314 }
00315 try {
00316 __mainloop_uc.add(mainloop_thread);
00317 mainloop_thread->init_MainLoopAspect(__btexec);
00318 thread->add_notification_listener(this);
00319 } catch (Exception &e) {
00320 CannotInitializeThreadException ce("Main loop thread failed to initialize");
00321 ce.append(e);
00322 throw ce;
00323 }
00324 }
00325
00326 LoggerAspect *logger_thread;
00327 if ( (logger_thread = dynamic_cast<LoggerAspect *>(thread)) != NULL ) {
00328 if ( __logger_employer == NULL ) {
00329 throw CannotInitializeThreadException("Thread has LoggerAspect but no "
00330 "LoggerEmployer has been set.");
00331 }
00332 try {
00333 __logger_employer->add_logger(logger_thread->get_logger());
00334 } catch (Exception &e) {
00335 CannotInitializeThreadException ce("Thread has LoggerAspect but Logger "
00336 "could not be added.");
00337 ce.append(e);
00338 throw ce;
00339 } catch (...) {
00340 throw CannotInitializeThreadException("Thread has LoggerAspect but Logger "
00341 "could not be added.");
00342 }
00343 }
00344 }
00345
00346
00347 bool
00348 AspectIniFin::prepare_finalize(Thread *thread)
00349 {
00350 #ifdef HAVE_FIREVISION
00351 VisionMasterAspect *vision_master_thread;
00352 if ( (vision_master_thread = dynamic_cast<VisionMasterAspect *>(thread)) != NULL ) {
00353 if ( ! __vision_dependency.can_remove(vision_master_thread) ) {
00354 __logger->log_error("AspectIniFin", "Cannot remove vision master, there are "
00355 "still vision threads that depend on it");
00356 return false;
00357 }
00358 }
00359
00360 VisionAspect *vision_thread;
00361 if ( (vision_thread = dynamic_cast<VisionAspect *>(thread)) != NULL ) {
00362 if ( ! __vision_dependency.can_remove(vision_thread) ) {
00363 __logger->log_error("AspectIniFin", "Cannot remove vision thread, dependency "
00364 "violation");
00365 return false;
00366 }
00367 }
00368 #endif
00369
00370 return true;
00371 }
00372
00373
00374
00375
00376
00377 void
00378 AspectIniFin::finalize(Thread *thread)
00379 {
00380 #ifdef HAVE_FIREVISION
00381 VisionMasterAspect *vision_master_thread;
00382 if ( (vision_master_thread = dynamic_cast<VisionMasterAspect *>(thread)) != NULL ) {
00383 try {
00384 __vision_dependency.remove(vision_master_thread);
00385 } catch (DependencyViolationException &e) {
00386 CannotFinalizeThreadException ce("Dependency violation for VisionProviderAspect "
00387 "detected");
00388 ce.append(e);
00389 throw ce;
00390 }
00391 }
00392
00393 VisionAspect *vision_thread;
00394 if ( (vision_thread = dynamic_cast<VisionAspect *>(thread)) != NULL ) {
00395 __vision_dependency.remove(vision_thread);
00396 }
00397 #endif
00398
00399 TimeSourceAspect *timesource_thread;
00400 if ( (timesource_thread = dynamic_cast<TimeSourceAspect *>(thread)) != NULL ) {
00401 try {
00402 __clock->remove_ext_timesource(timesource_thread->get_timesource());
00403 __timesource_uc.remove(timesource_thread->get_timesource());
00404 } catch (Exception &e) {
00405 CannotFinalizeThreadException ce("Failed to remove time source");
00406 ce.append(e);
00407 throw;
00408 }
00409 }
00410
00411 MainLoopAspect *mainloop_thread;
00412 if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
00413 try {
00414 if (__mainloop_uc.resource() == mainloop_thread) {
00415 __mainloop_employer->set_mainloop_thread(NULL);
00416 __mainloop_uc.remove(mainloop_thread);
00417 }
00418 } catch (Exception &e) {
00419 CannotFinalizeThreadException ce("Failed to remove main loop");
00420 ce.append(e);
00421 throw;
00422 }
00423 }
00424
00425 LoggerAspect *logger_thread;
00426 if ( (logger_thread = dynamic_cast<LoggerAspect *>(thread)) != NULL ) {
00427 try {
00428 __logger_employer->remove_logger(logger_thread->get_logger());
00429 } catch (Exception &e) {
00430 CannotFinalizeThreadException ce("Failed to remove logger");
00431 ce.append(e);
00432 throw;
00433 }
00434 }
00435 }
00436
00437
00438 bool
00439 AspectIniFin::thread_started(Thread *thread) throw()
00440 {
00441 MainLoopAspect *mainloop_thread;
00442 if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
00443 try {
00444 __mainloop_employer->set_mainloop_thread(thread);
00445 } catch (Exception &e) {
00446 __logger->log_error("AspectIniFin", "Main loop thread started successfully but "
00447 "could not add main loop thread's main loop");
00448 }
00449 }
00450
00451 return false;
00452 }
00453
00454
00455 bool
00456 AspectIniFin::thread_init_failed(Thread *thread) throw()
00457 {
00458 MainLoopAspect *mainloop_thread;
00459 if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
00460 try {
00461 __mainloop_uc.remove(mainloop_thread);
00462 } catch (Exception &e) {
00463 __logger->log_error("AspectIniFin", "Failed to remove main loop from uniqueness "
00464 "constraint on thread init fail of %s", thread->name());
00465 }
00466 }
00467
00468 try {
00469 finalize(thread);
00470 } catch (Exception &e) {
00471 __logger->log_error("AspectIniFin", "Initialization of thread '%s' failed, but "
00472 "the thread thread could not be internally finalized",
00473 thread->name());
00474 __logger->log_error("AspectIniFin", e);
00475 }
00476
00477 return false;
00478 }
00479
00480 }