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
37 #include <anna/core/tracing/Logger.hpp>
38 #include <anna/core/functions.hpp>
39 #include <anna/core/mt/Guard.hpp>
40 #include <anna/core/tracing/TraceMethod.hpp>
42 #include <anna/xml/Node.hpp>
43 #include <anna/xml/Attribute.hpp>
45 #include <anna/comm/internal/RemoteConnection.hpp>
46 #include <anna/comm/Communicator.hpp>
47 #include <anna/comm/Device.hpp>
48 #include <anna/comm/Server.hpp>
49 #include <anna/comm/ClientSocket.hpp>
50 #include <anna/comm/internal/ConnectionRecover.hpp>
51 #include <anna/comm/Receiver.hpp>
53 #include <anna/comm/handler/RemoteConnection.hpp>
58 //-------------------------------------------------------------------------------------------
60 // Host::createServer -> Server::connect -> Communicator::attach (RemoteConnection*) ->
61 // comm::handler::RemoteConnection::initialize
62 //-------------------------------------------------------------------------------------------
65 <Guard Id="0x7fbfffeb68" Name="comm::Communicator::multithreadedAccept (ConnectionRecover)" LineNo="635">
66 <Method Id="comm::Server::connect" File="comm.Server.cc" Line="149" LineNo="637">
67 <Guard Id="0x7fbfffeb68" Name="comm::Communicator from comm::Server::connect" LineNo="639" Mode="Reentrant">
68 <Guard Id="0x690f20" Name="comm::Server::connect" LineNo="641">
69 <Method Id="comm::handler::RemoteConnection::initialize" File="handler.db/comm.handler.RemoteConnection.cc" Line="54" LineNo="643">
70 <Guard Id="0x690ff0" Name="comm::ClientSocket (connect)" LineNo="645"/>
71 <Method Id="comm::Communicator::eventCreateConnection" File="comm.Communicator.cc" Line="723" LineNo="655">
72 <Method Id="comm::Delivery::recover" File="comm.Delivery.cc" Line="186" LineNo="659">
73 <Guard Id="0x690750" Name="comm::Delivery::recover" LineNo="661">
74 <Method Id="comm::Delivery::unsafe_recover" File="comm.Delivery.cc" Line="196" LineNo="663">
75 <Guard Id="0x690f20" Name="Resource" LineNo="665" Mode="Reentrant"/>
81 <Guard Id="0x68f378" Name="anna::ThreadManager::createThread" LineNo="681"/>
86 void comm::handler::RemoteConnection::initialize()
87 throw(RuntimeException) {
88 LOGMETHOD(TraceMethod traceMethod("comm::handler::RemoteConnection", "initialize", ANNA_FILE_LOCATION));
90 if(a_remoteConnection == NULL) {
91 string msg(asString());
92 msg += " | No se ha establecido el comm::RemoteConnection";
93 throw RuntimeException(msg, ANNA_FILE_LOCATION);
96 if(a_remoteConnection->getClientSocket() == NULL) {
97 string msg(asString());
98 msg += " | No se ha establecido el comm::ClientSocket";
99 throw RuntimeException(msg, ANNA_FILE_LOCATION);
102 comm::ClientSocket& clientSocket = *a_remoteConnection->getClientSocket();
103 comm::Server* server = a_remoteConnection->getServer();
106 if(clientSocket.isConnected() == false)
107 clientSocket.connect();
110 a_communicator->eventCreateConnection(server);
111 // Notificacion al Receiver (EDU Febrero 2012)
114 if((receiver = clientSocket.getReceiver()) != NULL)
115 receiver->eventCreateConnection(server);
117 setfd(clientSocket.getfd());
118 } catch(RuntimeException&) {
119 a_communicator->getConnectionRecover()->annotateFault(server);
124 comm::ClientSocket* comm::handler::RemoteConnection::getClientSocket()
126 return (a_remoteConnection != NULL) ? a_remoteConnection->getClientSocket() : NULL;
130 * Se invoca desde Communicator::detach.
132 * [Tx] -> Communicator
135 * Al caer en el parche 1.11.9 NO se mantenÃa el orden requerido de bloqueo:
136 <Method Id="comm::handler::MetaClientSocket::apply" File="handler.db/comm.handler.MetaClientSocket.cc" Line="45" LineNo="419" InitTime="03/12/2009 12:10:30">
137 <Guard Id="0x690ff0" Name="comm::ClientSocket from comm::handler::MetaClientSocket::apply" LineNo="421"/>
138 <Guard Id="0x7fbfffeb68" Name="comm::Communicator::detach" LineNo="427">
139 <Method Id="comm::handler::RemoteConnection::finalize" File="handler.db/comm.handler.RemoteConnection.cc" Line="101" LineNo="431">
140 <Guard Id="0x690f20" Name="comm::Server::reset" LineNo="433">
141 <Guard Id="0x690ff0" Name="comm::Socket::close" LineNo="435">
142 <Guard Id="0x685bc0" Name="PN7anna4comm16TransportFactoryE" LineNo="437"/>
145 <Method Id="comm::Communicator::eventBreakConnection (server)" File="comm.Communicator.cc" Line="790" LineNo="447">
146 <Method Id="comm::Delivery::fault" File="comm.Delivery.cc" Line="135" LineNo="451">
147 <Guard Id="0x690750" Name="comm::Delivery::fault" LineNo="453">
148 <Method Id="comm::Delivery::unsafe_fault" File="comm.Delivery.cc" Line="149" LineNo="455">
149 <Guard Id="0x690f20" Name="Resource" LineNo="457"/>
153 <Guard Id="0x7fbfffeb68" Name="comm::Communicator::setStatus" LineNo="469" Mode="Reentrant"/>
160 void comm::handler::RemoteConnection::finalize()
162 if(a_remoteConnection == NULL)
165 LOGMETHOD(TraceMethod traceMethod("comm::handler::RemoteConnection", "finalize", ANNA_FILE_LOCATION));
166 comm::Server* server = a_remoteConnection->getServer();
167 Guard guard(server, "comm::Server");
168 comm::ClientSocket* clientSocket = a_remoteConnection->getClientSocket();
170 if(clientSocket != NULL) {
173 if((receiver = clientSocket->getReceiver()) != NULL)
174 receiver->eventBreakConnection(*clientSocket);
176 a_communicator->eventBreakConnection(*clientSocket);
179 // Cierra el socket y lo libera
181 // Establece la información que gestiona el reintento de uso por parte de los servicios de reparto
183 server->setTimeStamp(functions::millisecond());
185 if(a_communicator->hasRequestedStop() == false) {
186 a_communicator->eventBreakConnection(server);
187 a_communicator->getConnectionRecover()->annotateFault(server);
190 delete a_remoteConnection;
191 a_remoteConnection = NULL;
197 void comm::handler::RemoteConnection::clone()
198 throw(RuntimeException) {
199 comm::ClientSocket& clientSocket = *a_remoteConnection->getClientSocket();
202 if(clientSocket.isConnected() == true)
203 clientSocket.close();
205 clientSocket.connect();
206 setfd(clientSocket.getfd());
207 } catch(RuntimeException&) {
208 a_communicator->getConnectionRecover()->annotateFault(a_remoteConnection->getServer());
213 string comm::handler::RemoteConnection::asString() const
215 string result("comm::handler::RemoteConnection { ");
216 result += comm::Handler::asString();
218 result += functions::asString(a_remoteConnection);
219 return result += " }";
222 xml::Node* comm::handler::RemoteConnection::asXML(xml::Node* parent) const
224 xml::Node* result = parent->createChild("comm.handler.RemoteConnection");
225 comm::Handler::asAttribute(result);
227 if(a_remoteConnection)
228 a_remoteConnection->asXML(result);