00001 /*************************************************************************** 00002 00003 socketmarshaller.cpp - description 00004 ------------------- 00005 begin : Mon August 7 2006 00006 copyright : (C) 2006 Bas Kemper 00007 email : kst@baskemper.be 00008 00009 *************************************************************************** 00010 * This library is free software; you can redistribute it and/or * 00011 * modify it under the terms of the GNU Lesser General Public * 00012 * License as published by the Free Software Foundation; either * 00013 * version 2.1 of the License, or (at your option) any later version. * 00014 * * 00015 * This library is distributed in the hope that it will be useful, * 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00018 * Lesser General Public License for more details. * 00019 * * 00020 * You should have received a copy of the GNU Lesser General Public * 00021 * License along with this library; if not, write to the Free Software * 00022 * Foundation, Inc., 59 Temple Place, * 00023 * Suite 330, Boston, MA 02111-1307 USA * 00024 * * 00025 ***************************************************************************/ 00026 00027 #include <rtt/Logger.hpp> 00028 #include <rtt/Property.hpp> 00029 #include <rtt/base/PropertyIntrospection.hpp> 00030 #include <rtt/os/Mutex.hpp> 00031 #include "TcpReporting.hpp" 00032 #include "socketmarshaller.hpp" 00033 #include "datasender.hpp" 00034 00035 using RTT::Logger; 00036 00037 namespace RTT 00038 { 00039 SocketMarshaller::SocketMarshaller(OCL::TcpReporting* reporter) 00040 : _reporter(reporter) 00041 { 00042 } 00043 00044 SocketMarshaller::~SocketMarshaller() 00045 { 00046 closeAllConnections(); 00047 } 00048 00049 void SocketMarshaller::addConnection(OCL::TCP::Socket* os) 00050 { 00051 lock.lock(); 00052 OCL::TCP::Datasender* conn = new OCL::TCP::Datasender(this, os); 00053 _connections.push_front( conn ); 00054 conn->Activity::start(); 00055 lock.unlock(); 00056 } 00057 00058 void SocketMarshaller::closeAllConnections() 00059 { 00060 // TODO: locking, proper connection shutdown 00061 while( !_connections.empty() ) 00062 { 00063 removeConnection( _connections.front() ); 00064 } 00065 } 00066 00067 void SocketMarshaller::flush() 00068 {} 00069 00070 void SocketMarshaller::removeConnection(OCL::TCP::Datasender* sender) 00071 { 00072 lock.lock(); 00073 _connections.remove( sender ); 00074 sender->breakLoop(); 00075 delete sender; 00076 lock.unlock(); 00077 } 00078 00079 OCL::TcpReporting* SocketMarshaller::getReporter() const 00080 { 00081 return _reporter; 00082 } 00083 00084 void SocketMarshaller::serialize(RTT::base::PropertyBase*) 00085 { 00086 // This method is pure virtual in the parent class. 00087 Logger::log() << Logger::Error << "Unexpected call to SocketMarshaller::serialize" << 00088 Logger::endl; 00089 } 00090 00091 void SocketMarshaller::serialize(const PropertyBag &v) 00092 { 00093 lock.lock(); 00094 // TODO: sending data does not run in parallel! 00095 for( std::list<OCL::TCP::Datasender*>::iterator it = _connections.begin(); 00096 it != _connections.end(); ) 00097 { 00098 if( (*it)->isValid() ) 00099 { 00100 (*it)->serialize(v); 00101 it++; 00102 } else { 00103 OCL::TCP::Datasender* torm = *it; 00104 it++; 00105 removeConnection( torm ); 00106 } 00107 } 00108 lock.unlock(); 00109 } 00110 00111 void SocketMarshaller::shutdown() 00112 { 00113 closeAllConnections(); 00114 } 00115 }