Orocos Real-Time Toolkit  2.9.0
ConnectionManager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 ConnectionManager.cpp
3 
4  ConnectionManager.cpp - description
5  -------------------
6  begin : Thu October 22 2009
7  copyright : (C) 2009 Peter Soetens
8  email : peter@thesourcworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 /*
40  * ConnectionManager.cpp
41  *
42  * Created on: Oct 9, 2009
43  * Author: kaltan
44  */
45 
46 #include "ConnectionManager.hpp"
47 #include <boost/bind.hpp>
48 #include <boost/scoped_ptr.hpp>
49 #include "../base/PortInterface.hpp"
50 #include "../os/MutexLock.hpp"
51 #include "../base/InputPortInterface.hpp"
52 #include "../Logger.hpp"
53 #include <cassert>
54 
55 namespace RTT
56 {
57  using namespace detail;
58 
59  namespace internal
60  {
61 
63  : mport(port)
64  {
65  }
66 
68  {
69  this->disconnect();
70  }
71 
73  {
74  boost::scoped_ptr<ConnID> conn_id( port->getPortID() );
75  return this->removeConnection(conn_id.get(), /* disconnect = */ true);
76  }
77 
78  ConnectionManager::Connections::iterator ConnectionManager::eraseConnection(const Connections::iterator& descriptor, bool disconnect)
79  {
80  base::ChannelElementBase::shared_ptr channel = descriptor->get<1>();
81 
82  // disconnect from a shared connection
83  if (channel == shared_connection) {
84  RTT::log(Debug) << "Port " << mport->getName() << " disconnected from shared connection " << shared_connection->getName() << RTT::endlog();
85  shared_connection.reset();
86  }
87  Connections::iterator next = connections.erase(descriptor); // invalidates descriptor
88 
89  if (disconnect) {
90  // disconnect needs to know if we're from Out->In (forward) or from In->Out
91  bool is_forward = true;
92  if ( dynamic_cast<InputPortInterface*>(mport) )
93  is_forward = false; // disconnect on input port = backward.
94 
95  mport->getEndpoint()->disconnect(channel, is_forward);
96  }
97 
98  return next;
99  }
100 
102  {
104  for(Connections::iterator conn_it = connections.begin(); conn_it != connections.end(); ) {
105  conn_it = eraseConnection(conn_it, true);
106  }
107  }
108 
110  { return !connections.empty(); }
111 
113  {
115  boost::scoped_ptr<ConnID> conn_id( port->getPortID() );
116  for(Connections::const_iterator conn_it = connections.begin(); conn_it != connections.end(); ++conn_it ) {
117  if (conn_it->get<0>() && conn_id->isSameID(*conn_it->get<0>())) return true;
118  }
119  return false;
120  }
121 
124  assert(conn_id);
125 
126  // check if the new connection is a shared connection
127  {
128  SharedConnectionBase::shared_ptr is_shared_connection = boost::dynamic_pointer_cast<SharedConnectionBase>(channel);
129  if (is_shared_connection) shared_connection.swap(is_shared_connection);
130  }
131 
132  // add ChannelDescriptor to the connections list
133  ChannelDescriptor descriptor = boost::make_tuple(conn_id, channel, policy);
134  connections.push_back(descriptor);
135 
136  return true;
137  }
138 
139  bool ConnectionManager::removeConnection(ConnID* conn_id, bool disconnect /* = true */)
140  {
142  bool found = false;
143  for(Connections::iterator conn_it = connections.begin(); conn_it != connections.end(); ) {
144  if (conn_it->get<0>() && conn_id->isSameID(*conn_it->get<0>())) {
145  conn_it = eraseConnection(conn_it, disconnect);
146  found = true;
147  } else {
148  conn_it++;
149  }
150  }
151  return found;
152  }
153 
155  {
157  bool found = false;
158  for(Connections::iterator conn_it = connections.begin(); conn_it != connections.end(); ) {
159  if (conn_it->get<1>() && channel == conn_it->get<1>()) {
160  conn_it = eraseConnection(conn_it, disconnect);
161  found = true;
162  } else {
163  conn_it++;
164  }
165  }
166  return found;
167  }
168 
169  }
170 
171 }
virtual bool isSameID(ConnID const &id) const =0
Connections::iterator eraseConnection(const Connections::iterator &descriptor, bool disconnect)
Helper method for disconnect()
boost::intrusive_ptr< SharedConnectionBase > shared_ptr
bool removeConnection(ConnID *port_id, bool disconnect=true)
void disconnect()
Disconnect all connections.
bool connectedTo(base::PortInterface *port)
Returns true if there exists a connection to the given port.
const std::string & getName() const
Get the name of this Port.
internal::SharedConnectionBase::shared_ptr shared_connection
A pointer to the shared connection this port may be connected to.
A connection policy object describes how a given connection should behave.
Definition: ConnPolicy.hpp:107
void lock() const
Locks the mutex protecting the channel element list.
virtual ChannelElementBase * getEndpoint() const =0
Returns the input or output endpoint of this port (if any).
ConnectionManager(base::PortInterface *port)
Creates a connection manager to manage the connections of port.
virtual void disconnect(bool forward)
Performs a disconnection of this channel&#39;s endpoints.
base::PortInterface * mport
The port for which we manage connections.
boost::tuple< boost::shared_ptr< ConnID >, base::ChannelElementBase::shared_ptr, ConnPolicy > ChannelDescriptor
A connection is described by an opaque ConnID object, the first element of the connection and the pol...
boost::intrusive_ptr< ChannelElementBase > shared_ptr
RTT::os::Mutex connection_lock
Lock that should be taken before the list of connections is accessed or modified. ...
bool addConnection(ConnID *port_id, base::ChannelElementBase::shared_ptr channel, ConnPolicy policy)
Helper method for port-to-port connection establishment.
virtual internal::ConnID * getPortID() const
Returns the identity of this port in a ConnID object.
This class is used in places where a permanent representation of a reference to a connection is neede...
Definition: ConnID.hpp:58
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
std::list< ChannelDescriptor > connections
A list of all our connections.
In the data flow implementation, a channel is created by chaining ChannelElementBase objects...
The base class of every data flow port.
bool connected() const
Returns true if there is at least one connection registered in this port&#39;s list of outputs...
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
Definition: MutexLock.hpp:51
Base class for shared connection elements.