Orocos Real-Time Toolkit  2.8.3
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 <cassert>
53 
54 namespace RTT
55 {
56  using namespace detail;
57 
58  namespace internal
59  {
60 
62  : mport(port)
63  , cur_channel(NULL)
64  {
65  }
66 
68  {
69  this->disconnect();
70  }
71 
77  descriptor.get<1>()->clear();
78  }
79 
82  std::for_each(connections.begin(), connections.end(), &clearChannel);
83  }
84 
85  bool ConnectionManager::findMatchingPort(ConnID const* conn_id, ChannelDescriptor const& descriptor)
86  {
87  return ( descriptor.get<0>() && conn_id->isSameID(*descriptor.get<0>()));
88  }
89 
90  void ConnectionManager::updateCurrentChannel(bool reset_current)
91  {
92  if (connections.empty())
93  cur_channel = NULL;
94  else if (reset_current)
95  cur_channel = &(connections.front());
96  }
97 
99  {
100  boost::scoped_ptr<ConnID> conn_id( port->getPortID() );
101  return this->removeConnection(conn_id.get());
102  }
103 
105  {
106  // disconnect needs to know if we're from Out->In (forward) or from In->Out
107  bool is_forward = true;
108  if ( dynamic_cast<InputPortInterface*>(mport) )
109  is_forward = false; // disconnect on input port = backward.
110 
111  descriptor.get<1>()->disconnect( is_forward );
112  return true;
113  }
114 
116  {
117  std::list<ChannelDescriptor> all_connections;
119  all_connections.splice(all_connections.end(), connections);
120  cur_channel = NULL;
121  }
122  std::for_each(all_connections.begin(), all_connections.end(),
123  boost::bind(&ConnectionManager::eraseConnection, this, _1));
124  }
125 
127  { return !connections.empty(); }
128 
129 
132  assert(conn_id);
133  ChannelDescriptor descriptor = boost::make_tuple(conn_id, channel, policy);
134  connections.insert(connections.end(), descriptor);
135  if (connections.size() == 1)
136  cur_channel = &(connections.front());
137  }
138 
140  {
141  ChannelDescriptor descriptor;
143  std::list<ChannelDescriptor>::iterator conn_it =
144  std::find_if(connections.begin(), connections.end(), boost::bind(&ConnectionManager::findMatchingPort, this, conn_id, _1));
145  if (conn_it == connections.end())
146  return false;
147  descriptor = *conn_it;
148  // Verify whether cur_channel is conn_it before we erase, as
149  // cur_channel is a pointer to an element in connections
150  bool reset_current = cur_channel && (cur_channel->get<1>() == descriptor.get<1>());
151  connections.erase(conn_it);
152  updateCurrentChannel(reset_current);
153  }
154 
155  // disconnect needs to know if we're from Out->In (forward) or from In->Out
156  bool is_forward = true;
157  if ( dynamic_cast<InputPortInterface*>(mport) )
158  is_forward = false; // disconnect on input port = backward.
159 
160  descriptor.get<1>()->disconnect(is_forward);
161  return true;
162  }
163 
165  {
166  return conn_id->isSameID( *channel.get<0>() );
167  }
168 
169  }
170 
171 }
virtual bool isSameID(ConnID const &id) const =0
void addConnection(ConnID *port_id, base::ChannelElementBase::shared_ptr channel_input, ConnPolicy policy)
Helper method for port-to-port connection establishment.
void disconnect()
Disconnect all connections.
bool removeConnection(ConnID *port_id)
void clear()
Clears (removes) all data in the manager&#39;s connections.
ChannelDescriptor * cur_channel
Optimisation in case only one channel is to be managed.
A connection policy object describes how a given connection should behave.
Definition: ConnPolicy.hpp:92
void lock() const
Locks the mutex protecting the channel element list.
bool findMatchingPort(ConnID const *conn_id, ChannelDescriptor const &descriptor)
Helper method for disconnect(PortInterface*)
ConnectionManager(base::PortInterface *port)
Creates a connection manager to manage the connections of port.
base::PortInterface * mport
The port for which we manage connections.
bool is_same_id(ConnID *conn_id, ConnectionManager::ChannelDescriptor const &channel)
void updateCurrentChannel(bool reset_current)
boost::tuple< boost::shared_ptr< ConnID >, base::ChannelElementBase::shared_ptr, ConnPolicy > ChannelDescriptor
A Channel (= connection) is described by an opaque ConnID object, the first element of the channel an...
void clearChannel(ConnectionManager::ChannelDescriptor &descriptor)
Helper function to clear a connection.
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. ...
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:51
std::list< ChannelDescriptor > connections
A list of all our connections.
The base class of every data flow port.
bool eraseConnection(ChannelDescriptor &descriptor)
Helper method for disconnect()
bool connected() const
Returns true if there is at least one channel 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