Fawkes API  Fawkes Development Version
mainloop.cpp
1 
2 /***************************************************************************
3  * mainloop.cpp - Fawkes MainLoopAspect initializer/finalizer
4  *
5  * Created: Wed Nov 24 00:44:55 2010
6  * Copyright 2006-2010 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <aspect/inifins/mainloop.h>
25 #include <aspect/mainloop.h>
26 #include <aspect/mainloop/employer.h>
27 #include <aspect/blocked_timing/executor.h>
28 #include <core/threading/thread_finalizer.h>
29 
30 namespace fawkes {
31 #if 0 /* just to make Emacs auto-indent happy */
32 }
33 #endif
34 
35 /** @class MainLoopAspectIniFin <aspect/inifins/mainloop.h>
36  * Initializer/finalizer for the MainLoopAspect.
37  * @author Tim Niemueller
38  */
39 
40 /** Constructor.
41  * @param employer main loop employer to register main loop to
42  * @param btexec blocked timing executor to pass to thread
43  */
45  BlockedTimingExecutor *btexec)
46  : AspectIniFin("MainLoopAspect")
47 {
48  __employer = employer;
49  __btexec = btexec;
50 }
51 
52 
53 void
55 {
56  MainLoopAspect *mainloop_thread;
57  mainloop_thread = dynamic_cast<MainLoopAspect *>(thread);
58  if (mainloop_thread == NULL) {
59  throw CannotInitializeThreadException("Thread '%s' claims to have the "
60  "MainLoopAspect, but RTTI says it "
61  "has not. ", thread->name());
62  }
63 
64  if (thread->opmode() != Thread::OPMODE_WAITFORWAKEUP) {
65  throw CannotInitializeThreadException("MainLoopAspect thread must operate "
66  "in wait-for-wakeup mode.");
67  }
68 
69  try {
70  __mainloop_uc.add(mainloop_thread);
71  mainloop_thread->init_MainLoopAspect(__btexec);
72  thread->add_notification_listener(this);
73  } catch (Exception &e) {
74  CannotInitializeThreadException ce("Main loop thread failed to initialize");
75  ce.append(e);
76  throw ce;
77  }
78 }
79 
80 
81 void
83 {
84  MainLoopAspect *mainloop_thread;
85  mainloop_thread = dynamic_cast<MainLoopAspect *>(thread);
86  if (mainloop_thread == NULL) {
87  throw CannotInitializeThreadException("Thread '%s' claims to have the "
88  "MainLoopAspect, but RTTI says it "
89  "has not. ", thread->name());
90  }
91 
92  try {
93  __employer->set_mainloop_thread(NULL);
94  __mainloop_uc.remove(mainloop_thread);
95  } catch (Exception &e) {
96  CannotFinalizeThreadException ce("Failed to remove time source");
97  ce.append(e);
98  throw;
99  }
100 }
101 
102 
103 bool
105 {
106  MainLoopAspect *mainloop_thread;
107  if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
108  try {
109  __employer->set_mainloop_thread(thread);
110  } catch (Exception &e) {
111  //__logger->log_error("AspectIniFin", "Main loop thread started successfully "
112  // "but could not add main loop thread's main loop");
113  }
114  }
115 
116  return false;
117 }
118 
119 
120 bool
122 {
123  MainLoopAspect *mainloop_thread;
124  if ( (mainloop_thread = dynamic_cast<MainLoopAspect *>(thread)) != NULL ) {
125  try {
126  __mainloop_uc.remove(mainloop_thread);
127  } catch (Exception &e) {
128  //__logger->log_error("AspectIniFin", "Failed to remove main loop from "
129  // "uniqueness constraint on thread init fail of %s",
130  // thread->name());
131  }
132  }
133 
134  try {
135  finalize(thread);
136  } catch (Exception &e) {
137  /*
138  __logger->log_error("AspectIniFin", "Initialization of thread '%s' failed, but "
139  "the thread thread could not be internally finalized",
140  thread->name());
141  __logger->log_error("AspectIniFin", e);
142  */
143  }
144 
145  return false;
146 }
147 
148 
149 } // end namespace fawkes
void add_notification_listener(ThreadNotificationListener *notification_listener)
Add notification listener.
Definition: thread.cpp:1170
virtual void set_mainloop_thread(Thread *mainloop_thread)=0
Set a new main loop.
Thread aspect that allows to replace the main loop of the main application of Fawkes.
Definition: mainloop.h:37
Fawkes library namespace.
virtual bool thread_init_failed(Thread *thread)
Thread initialization failed.
Definition: mainloop.cpp:121
Thread class encapsulation of pthreads.
Definition: thread.h:42
OpMode opmode() const
Get operation mode.
Definition: thread.cpp:678
virtual bool thread_started(Thread *thread)
Thread started successfully.
Definition: mainloop.cpp:104
Thread cannot be initialized.
Base class for exceptions in Fawkes.
Definition: exception.h:36
Blocked timing executor.
Definition: executor.h:35
virtual void finalize(Thread *thread)
Finalize thread.
Definition: mainloop.cpp:82
const char * name() const
Get name of thread.
Definition: thread.h:95
virtual void init(Thread *thread)
Initialize thread.
Definition: mainloop.cpp:54
void init_MainLoopAspect(BlockedTimingExecutor *btexec)
Initialize main loop aspect.
Definition: mainloop.cpp:68
Main loop employer The MainLoopEmployer calls the main loop for execution.
Definition: employer.h:31
Thread cannot be finalized.
MainLoopAspectIniFin(MainLoopEmployer *employer, BlockedTimingExecutor *btexec)
Constructor.
Definition: mainloop.cpp:44
operate in wait-for-wakeup mode
Definition: thread.h:54
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
Aspect initializer/finalizer base class.
Definition: inifin.h:36