IBR-DTNSuite 0.6

daemon/src/core/EventSwitch.cpp

Go to the documentation of this file.
00001 /*
00002  * EventSwitch.cpp
00003  *
00004  *  Created on: 05.03.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "core/EventSwitch.h"
00009 
00010 #include <ibrcommon/thread/MutexLock.h>
00011 #include "core/GlobalEvent.h"
00012 #include <stdexcept>
00013 #include <iostream>
00014 using namespace std;
00015 
00016 namespace dtn
00017 {
00018         namespace core
00019         {
00020                 EventSwitch::EventSwitch()
00021                  : _running(false)
00022                 {
00023                 }
00024 
00025                 EventSwitch::~EventSwitch()
00026                 {
00027                         componentDown();
00028                 }
00029 
00030                 void EventSwitch::componentUp()
00031                 {
00032                 }
00033 
00034                 void EventSwitch::componentDown()
00035                 {
00036                         try {
00037                                 while (true)
00038                                 {
00039                                         Event *evt = _queue.getnpop();
00040                                         delete evt;
00041                                 }
00042                         } catch (const ibrcommon::QueueUnblockedException&) {
00043 
00044                         }
00045 
00046                         _running = false;
00047                         _queue.abort();
00048                 }
00049 
00050                 void EventSwitch::loop()
00051                 {
00052                         _running = true;
00053 
00054                         try {
00055                                 while (_running)
00056                                 {
00057                                         Event *evt = _queue.getnpop(true);
00058 
00059                                         try
00060                                         {
00061                                                 {
00062                                                         ibrcommon::MutexLock reglock(_receiverlock);
00063 
00064                                                         // forward to debugger
00065                                                         _debugger.raiseEvent(evt);
00066 
00067                                                         try {
00068                                                                 // get the list for this event
00069                                                                 const list<EventReceiver*> receivers = getReceivers(evt->getName());
00070 
00071                                                                 for (list<EventReceiver*>::const_iterator iter = receivers.begin(); iter != receivers.end(); iter++)
00072                                                                 {
00073                                                                         try {
00074                                                                                 (*iter)->raiseEvent(evt);
00075                                                                         } catch (...) {
00076                                                                                 // An error occurred during event raising
00077                                                                         }
00078                                                                 }
00079                                                         } catch (const NoReceiverFoundException&) {
00080                                                                 // No receiver available!
00081                                                         }
00082                                                 }
00083 
00084                                                 dtn::core::GlobalEvent *global = dynamic_cast<dtn::core::GlobalEvent*>(evt);
00085                                                 if (global != NULL)
00086                                                 {
00087                                                         if (global->getAction() == dtn::core::GlobalEvent::GLOBAL_SHUTDOWN)
00088                                                         {
00089                                                                 _running = false;
00090                                                         }
00091                                                 }
00092                                         } catch (const std::exception&) {
00093                                                 _running = false;
00094                                         }
00095 
00096                                         delete evt;
00097                                 }
00098                         } catch (const std::exception&) {
00099                                 _running = false;
00100                         }
00101                 }
00102 
00103                 const list<EventReceiver*>& EventSwitch::getReceivers(string eventName) const
00104                 {
00105                         map<string,list<EventReceiver*> >::const_iterator iter = _list.find(eventName);
00106 
00107                         if (iter == _list.end())
00108                         {
00109                                 throw NoReceiverFoundException();
00110                         }
00111 
00112                         return iter->second;
00113                 }
00114 
00115                 void EventSwitch::registerEventReceiver(string eventName, EventReceiver *receiver)
00116                 {
00117                         // get the list for this event
00118                         EventSwitch &s = EventSwitch::getInstance();
00119                         ibrcommon::MutexLock l(s._receiverlock);
00120                         s._list[eventName].push_back(receiver);
00121                 }
00122 
00123                 void EventSwitch::unregisterEventReceiver(string eventName, EventReceiver *receiver)
00124                 {
00125                         // get the list for this event
00126                         EventSwitch &s = EventSwitch::getInstance();
00127                         ibrcommon::MutexLock l(s._receiverlock);
00128                         s._list[eventName].remove( receiver );
00129                 }
00130 
00131                 void EventSwitch::raiseEvent(Event *evt)
00132                 {
00133                         EventSwitch &s = EventSwitch::getInstance();
00134                         s._queue.push(evt);
00135                 }
00136 
00137                 EventSwitch& EventSwitch::getInstance()
00138                 {
00139                         static EventSwitch instance;
00140                         return instance;
00141                 }
00142 
00143                 const std::string EventSwitch::getName() const
00144                 {
00145                         return "EventSwitch";
00146                 }
00147 
00148                 void EventSwitch::clear()
00149                 {
00150                         ibrcommon::MutexLock l(_receiverlock);
00151                         _list.clear();
00152                 }
00153         }
00154 }