Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/message/manager.cc

Go to the documentation of this file.
00001 /*
00002  * lib/message/manager.cc
00003  * 
00004  * Message handling "system" for errors, warnings and verbose messages. 
00005  * Message manager implementation. 
00006  * 
00007  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00008  * 
00009  * This file may be distributed and/or modified under the terms of the 
00010  * GNU General Public License version 2 as published by the Free Software 
00011  * Foundation. (See COPYING.GPL for details.)
00012  * 
00013  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00014  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00015  * 
00016  */
00017 
00018 #include "manager.h"
00019 #include "handler.h"
00020 
00021 
00022 // Initializing static data: 
00023 MessageManager *MessageManager::manager=NULL;
00024 
00025 
00026 void MessageManager::_PostMessage(const Message &m)
00027 {
00028     if(!this)  return;
00029     
00030     // If the message is not needed by any client, we can bail 
00031     // out early. 
00032     // Actually, we should not even be here in this case, but oh well...
00033     if(!_IsRequestedType(m.type()))  return;
00034     
00035     main_mutex.lock();
00036     
00037     // Deliver to all clients: 
00038     for(MessageHandler *_hdl=hdl_list.first(); _hdl; )
00039     {
00040         // If you don't know why these two lines are here, then leave 
00041         // them untouched. (They ARE necessary!) 
00042         MessageHandler *hdl=_hdl;
00043         _hdl=_hdl->next;
00044         
00045         if(m.MatchesTypeMask(hdl->mtmask))
00046         {  hdl->HandleMessage(m);  }
00047     }
00048     
00049     // In case it is a fatal error, we need to exit. 
00050     bool is_fatal=(m.type() & Message::MTFatal);
00051     bool must_exit = is_fatal && exit_on_fatal;
00052     
00053     main_mutex.unlock();
00054     
00055     if(must_exit)
00056     {
00057         // It's time to say goodbye...
00058         exit(2);
00059     }
00060 }
00061 
00062 
00063 void MessageManager::_RecomputeMTMask()
00064 {
00065     // (NOT mutex-protected!)
00066     
00067     // OR together again: 
00068     int all_mask=0;
00069     for(MessageHandler *hdl=hdl_list.first(); hdl; hdl=hdl->next)
00070     {  all_mask|=hdl->mtmask;  }
00071     
00072     // Update global type mask. 
00073     type_mask.set(all_mask);
00074 }
00075 
00076 
00077 void MessageManager::_SelectMessageTypes(MessageHandler *hdl,
00078     Message::Type mask)
00079 {
00080     if(!this)  return;
00081     
00082     main_mutex.lock();
00083     
00084     // (Needs to be stored; bit removal problem :)
00085     hdl->mtmask=mask;
00086     
00087     _RecomputeMTMask();
00088     
00089     main_mutex.unlock();
00090 }
00091 
00092 
00093 void MessageManager::_RegisterHandler(MessageHandler *hdl)
00094 {
00095     if(!this || !hdl)  return;
00096     
00097     main_mutex.lock();
00098     hdl->mtmask=Message::MTNone;
00099     hdl_list.append(hdl);
00100     main_mutex.unlock();
00101 }
00102 
00103 void MessageManager::_UnregisterHandler(MessageHandler *hdl)
00104 {
00105     if(!this || !hdl)  return;
00106     
00107     main_mutex.lock();
00108     hdl_list.dequeue(hdl);
00109     _RecomputeMTMask();
00110     main_mutex.unlock();
00111 }
00112 
00113 
00114 void MessageManager::init()
00115 {
00116     // Initialize the manager. 
00117     new MessageManager();  // <-- Constructor will set MessageManager::manager. 
00118 }
00119 
00120 
00121 void MessageManager::cleanup()
00122 {
00123     if(manager)
00124     {  delete manager;  }
00125     // manager=NULL here by destructor of MessageManager. 
00126 }
00127 
00128 
00129 MessageManager::MessageManager() : 
00130     hdl_list(),
00131     main_mutex()
00132 {
00133     // This is needed as we use an atomic integer for mask storage. 
00134     CritAssert(sizeof(int)>=sizeof(Message::Type));  // critical
00135     
00136     type_mask=0;
00137     
00138     exit_on_fatal=1;
00139     
00140     Assert(!manager);
00141     manager=this;
00142 }
00143 
00144 
00145 MessageManager::~MessageManager()
00146 {
00147     Assert(manager==this);
00148     
00149     // Simply ignore the managers in the list. We dequeue them 
00150     // and leave them alone. 
00152     main_mutex.lock();
00153     while(!hdl_list.IsEmpty())
00154     {  _UnregisterHandler(hdl_list.first());  }
00155     main_mutex.unlock();
00156     
00157     manager=NULL;
00158 }
00159 
00160 

Generated on Sat Feb 19 22:33:45 2005 for Ray by doxygen 1.3.5