Remove dynamic exceptions
[anna.git] / source / diameter.comm / TimerManager.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 // Local
10 #include <anna/diameter.comm/TimerManager.hpp>
11 #include <anna/diameter.comm/Response.hpp>
12 #include <anna/diameter.comm/Session.hpp>
13
14 #include <anna/core/tracing/Logger.hpp>
15 #include <anna/app/functions.hpp>
16 #include <anna/timex/Engine.hpp>
17
18
19 using namespace std;
20 using namespace anna::diameter::comm;
21
22
23 TimerManager::TimerManager() :
24   anna::timex::TimeEventObserver("anna::diameter::comm::TimerManager"),
25   a_timeController(NULL) {
26 }
27
28 //-------------------------------------------------------------------------------------------------------
29 // (1) Bloquea el TimerManager el primero para mantener siempre el mismo orden de acceso a la
30 // seccion critica, lo que evita interbloqueos.
31 //-------------------------------------------------------------------------------------------------------
32 Timer* TimerManager::createTimer(Session* session, const anna::diameter::comm::Timer::Type::_v type)
33 noexcept(false) {
34   Timer* result(NULL);
35
36   if(a_timeController == NULL)
37     a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
38
39   anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer");              // (1)
40   result = a_timers.create();
41   result->setType(type);
42   result->setId((anna::timex::TimeEvent::Id) session);
43   result->setObserver(this);
44   result->setContext(session);
45   //Timeout depends on type:
46   // - SessionUnbind: temporizador de cierre local (2*Tx) como proteccion
47   // - SessionRecover: de momento no lo estamos usando, quiza por ello, el activateActionTimer debiera llamarse activateUnbindTimer...
48   result->setTimeout((anna::Millisecond)(2 * session->getClassCodeTimeout(ClassCode::ApplicationMessage).getValue()));
49   LOGDEBUG(
50     string msg("anna::diameter::comm::TimerManager::createTimer (actionTimer) | ");
51     msg += result->asString();
52     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
53   );
54   a_timeController->activate(result);
55   return result;
56 }
57
58
59 Timer* TimerManager::createTimer(Response* response)
60 noexcept(false) {
61   Timer* result(NULL);
62
63   if(a_timeController == NULL)
64     a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
65
66   anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer");              // (1)
67   result = a_timers.create();
68   const ClassCode::_v v = response->getClassCode();
69   result->setType(Timer::Type::ResponseExpiration);
70   result->setId((anna::timex::TimeEvent::Id) response);
71   result->setObserver(this);
72   result->setContext(response);
73   result->setTimeout(response->getSession()->getClassCodeTimeout(v));
74   // DWR doesn't arrive here: no context manage for this message
75   //if (response->isKeepAlive()) result->setTimeout(response->getSession()->getTimeout());
76   LOGDEBUG(
77     string msg("anna::diameter::comm::TimerManager::createTimer (response) | ");
78     msg += result->asString();
79     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
80   );
81   a_timeController->activate(result);
82   return result;
83 }
84
85
86 Timer* TimerManager::createTimer(LocalServer* localServer)
87 noexcept(false) {
88   Timer* result(NULL);
89
90   if(a_timeController == NULL)
91     a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
92
93   anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer");              // (1)
94   result = a_timers.create();
95   result->setType(Timer::Type::LocalServerAttach);
96   result->setId((anna::timex::TimeEvent::Id) localServer);
97   result->setObserver(this);
98   result->setContext(localServer);
99   result->setTimeout((anna::Millisecond)5000); // inactivityTime / 2 perhaps ??
100   LOGDEBUG(
101     string msg("anna::diameter::comm::TimerManager::createTimer (attachPlanning) | ");
102     msg += result->asString();
103     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
104   );
105   a_timeController->activate(result);
106   return result;
107 }
108
109
110 void TimerManager::cancelTimer(Timer* timer)
111 {
112   if(timer == NULL)
113     return;
114
115   LOGDEBUG(
116     string msg("anna::diameter::comm::TimerManager::cancel | ");
117     msg += timer->asString();
118     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
119   );
120
121   try {
122     if(a_timeController == NULL)
123       a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
124
125     a_timeController->cancel(timer);
126   } catch(anna::RuntimeException& ex) {
127     ex.trace();
128   }
129 }
130
131 //------------------------------------------------------------------------------------------
132 // Se invoca automaticamente desde anna::timex::Engine
133 //------------------------------------------------------------------------------------------
134 void TimerManager::release(anna::timex::TimeEvent* timeEvent)
135 {
136   Timer* timer = static_cast <Timer*>(timeEvent);
137   timer->setContext(NULL);
138   a_timers.release(timer);
139 }
140