1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 #include <anna/diameter.comm/TimerManager.hpp>
39 #include <anna/diameter.comm/Response.hpp>
40 #include <anna/diameter.comm/Session.hpp>
42 #include <anna/core/tracing/Logger.hpp>
43 #include <anna/app/functions.hpp>
44 #include <anna/timex/Engine.hpp>
48 using namespace anna::diameter::comm;
51 TimerManager::TimerManager() :
52 anna::timex::TimeEventObserver("anna::diameter::comm::TimerManager"),
53 a_timeController(NULL) {
56 //-------------------------------------------------------------------------------------------------------
57 // (1) Bloquea el TimerManager el primero para mantener siempre el mismo orden de acceso a la
58 // seccion critica, lo que evita interbloqueos.
59 //-------------------------------------------------------------------------------------------------------
60 Timer* TimerManager::createTimer(Session* session, const anna::diameter::comm::Timer::Type::_v type)
61 throw(anna::RuntimeException) {
64 if(a_timeController == NULL)
65 a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
67 anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer"); // (1)
68 result = a_timers.create();
69 result->setType(type);
70 result->setId((anna::timex::TimeEvent::Id) session);
71 result->setObserver(this);
72 result->setContext(session);
73 //Timeout depends on type:
74 // - SessionUnbind: temporizador de cierre local (2*Tx) como proteccion
75 // - SessionRecover: de momento no lo estamos usando, quiza por ello, el activateActionTimer debiera llamarse activateUnbindTimer...
76 result->setTimeout((anna::Millisecond)(2 * session->getClassCodeTimeout(ClassCode::ApplicationMessage).getValue()));
78 string msg("anna::diameter::comm::TimerManager::createTimer (actionTimer) | ");
79 msg += result->asString();
80 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
82 a_timeController->activate(result);
87 Timer* TimerManager::createTimer(Response* response)
88 throw(anna::RuntimeException) {
91 if(a_timeController == NULL)
92 a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
94 anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer"); // (1)
95 result = a_timers.create();
96 const ClassCode::_v v = response->getClassCode();
97 result->setType(Timer::Type::ResponseExpiration);
98 result->setId((anna::timex::TimeEvent::Id) response);
99 result->setObserver(this);
100 result->setContext(response);
101 result->setTimeout(response->getSession()->getClassCodeTimeout(v));
102 // DWR doesn't arrive here: no context manage for this message
103 //if (response->isKeepAlive()) result->setTimeout(response->getSession()->getTimeout());
105 string msg("anna::diameter::comm::TimerManager::createTimer (response) | ");
106 msg += result->asString();
107 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
109 a_timeController->activate(result);
114 Timer* TimerManager::createTimer(LocalServer* localServer)
115 throw(anna::RuntimeException) {
118 if(a_timeController == NULL)
119 a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
121 anna::Guard guard(a_timeController, "anna::diameter::comm::TimerManager::createTimer"); // (1)
122 result = a_timers.create();
123 result->setType(Timer::Type::LocalServerAttach);
124 result->setId((anna::timex::TimeEvent::Id) localServer);
125 result->setObserver(this);
126 result->setContext(localServer);
127 result->setTimeout((anna::Millisecond)5000); // inactivityTime / 2 perhaps ??
129 string msg("anna::diameter::comm::TimerManager::createTimer (attachPlanning) | ");
130 msg += result->asString();
131 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
133 a_timeController->activate(result);
138 void TimerManager::cancelTimer(Timer* timer)
144 string msg("anna::diameter::comm::TimerManager::cancel | ");
145 msg += timer->asString();
146 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
150 if(a_timeController == NULL)
151 a_timeController = anna::app::functions::component <anna::timex::Engine> (ANNA_FILE_LOCATION);
153 a_timeController->cancel(timer);
154 } catch(anna::RuntimeException& ex) {
159 //------------------------------------------------------------------------------------------
160 // Se invoca automaticamente desde anna::timex::Engine
161 //------------------------------------------------------------------------------------------
162 void TimerManager::release(anna::timex::TimeEvent* timeEvent)
164 Timer* timer = static_cast <Timer*>(timeEvent);
165 timer->setContext(NULL);
166 a_timers.release(timer);