ConnFactory.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 ConnFactory.hpp
3 
4  ConnFactory.hpp - 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 #ifndef ORO_CONN_FACTORY_HPP
40 #define ORO_CONN_FACTORY_HPP
41 
42 #include <string>
43 #include "Channels.hpp"
44 #include "ConnInputEndPoint.hpp"
45 #include "ConnOutputEndPoint.hpp"
46 #include "PortConnectionLock.hpp"
47 #include "SharedConnection.hpp"
48 #include "../base/PortInterface.hpp"
49 #include "../base/InputPortInterface.hpp"
50 #include "../base/OutputPortInterface.hpp"
51 #include "../DataFlowInterface.hpp"
52 
53 #include "../base/DataObject.hpp"
54 #include "../base/DataObjectUnSync.hpp"
55 #include "../base/Buffer.hpp"
56 #include "../base/BufferUnSync.hpp"
57 #include "../Logger.hpp"
58 
59 #include "../rtt-config.h"
60 
61 namespace RTT
62 { namespace internal {
63 
67  struct LocalConnID : public ConnID
68  {
71  : ptr(obj) {}
72  virtual ConnID* clone() const;
73  virtual bool isSameID(ConnID const& id) const;
74  };
75 
79  struct RTT_API StreamConnID : public ConnID
80  {
81  std::string name_id;
82  StreamConnID(const std::string& name)
83  : name_id(name) {}
84  virtual ConnID* clone() const;
85  virtual bool isSameID(ConnID const& id) const;
86  };
87 
88 
95  class RTT_API ConnFactory
96  {
97  public:
98  virtual ~ConnFactory() {}
99 
104  virtual base::InputPortInterface* inputPort(std::string const& name) const = 0;
105 
110  virtual base::OutputPortInterface* outputPort(std::string const& name) const = 0;
111 
118  virtual base::ChannelElementBase::shared_ptr buildDataStorage(ConnPolicy const& policy) const = 0;
119 
127  virtual base::ChannelElementBase::shared_ptr buildChannelOutput(base::InputPortInterface& port, ConnPolicy const& policy) const = 0;
128 
136  virtual base::ChannelElementBase::shared_ptr buildChannelInput(base::OutputPortInterface& port, ConnPolicy const& policy) const = 0;
137 
148  virtual internal::SharedConnectionBase::shared_ptr buildSharedConnection(base::OutputPortInterface *output_port, base::InputPortInterface *input_port, ConnPolicy const& policy) const = 0;
149 
157  template<typename T>
158  static base::ChannelElement<T>* buildDataStorage(ConnPolicy const& policy, const T& initial_value = T())
159  {
160  if (policy.type == ConnPolicy::DATA)
161  {
162  typename base::DataObjectInterface<T>::shared_ptr data_object;
163  switch (policy.lock_policy)
164  {
165 #ifndef OROBLD_OS_NO_ASM
167  data_object.reset( new base::DataObjectLockFree<T>(initial_value, policy) );
168  break;
169 #else
171  RTT::log(Warning) << "lock free connection policy is unavailable on this system, defaulting to LOCKED" << RTT::endlog();
172 #endif
173  case ConnPolicy::LOCKED:
174  data_object.reset( new base::DataObjectLocked<T>(initial_value) );
175  break;
176  case ConnPolicy::UNSYNC:
177  data_object.reset( new base::DataObjectUnSync<T>(initial_value) );
178  break;
179  }
180  return new ChannelDataElement<T>(data_object, policy);
181  }
182  else if (policy.type == ConnPolicy::BUFFER || policy.type == ConnPolicy::CIRCULAR_BUFFER)
183  {
184  typename base::BufferInterface<T>::shared_ptr buffer_object;
185  switch (policy.lock_policy)
186  {
187 #ifndef OROBLD_OS_NO_ASM
189  buffer_object.reset(new base::BufferLockFree<T>(policy.size, initial_value, policy));
190  break;
191 #else
193  RTT::log(Warning) << "lock free connection policy is unavailable on this system, defaulting to LOCKED" << RTT::endlog();
194 #endif
195  case ConnPolicy::LOCKED:
196  buffer_object.reset(new base::BufferLocked<T>(policy.size, initial_value, policy));
197  break;
198  case ConnPolicy::UNSYNC:
199  buffer_object.reset(new base::BufferUnSync<T>(policy.size, initial_value, policy));
200  break;
201  }
202  return new ChannelBufferElement<T>(buffer_object, policy);
203  }
204  return NULL;
205  }
206 
219  template<typename T>
220  static base::ChannelElementBase::shared_ptr buildChannelInput(OutputPort<T>& port, ConnPolicy const& policy, bool force_unbuffered = false)
221  {
222  typename internal::ConnInputEndpoint<T>::shared_ptr endpoint = port.getEndpoint();
223 
224  // Note: PerInputPort implies PUSH and PerOutputPort implies PULL
225  bool pull = policy.pull;
226  if (policy.buffer_policy == PerInputPort) pull = ConnPolicy::PUSH;
227  if (policy.buffer_policy == PerOutputPort) pull = ConnPolicy::PULL;
228 
229  // Special case: PerOutputPort
230  typename base::ChannelElement<T>::shared_ptr buffer = port.getSharedBuffer();
231  if (policy.buffer_policy == PerOutputPort) {
232  if (!buffer) {
233  if (endpoint->connected()) {
234  log(Error) << "You tried to create a shared output buffer connection for output port " << port.getName() << ", "
235  << "but the port already has at least one incompatible outgoing connection." << endlog();
237  }
238 
239  buffer = buildDataStorage<T>(policy, port.getLastWrittenValue());
240  if (!buffer) return base::ChannelElementBase::shared_ptr();
241 
242  // For PerOutputPort connections, the buffer is installed BEFORE the output endpoint!
243  if (!buffer->connectTo(endpoint)) {
245  }
246  } else {
247  // check that the existing buffer type is compatible to the new ConnPolicy
248  assert(buffer->getConnPolicy());
249  ConnPolicy buffer_policy = *(buffer->getConnPolicy());
250 
251  if (
252  (buffer_policy.type != policy.type) ||
253  (buffer_policy.size != policy.size) ||
254  (buffer_policy.lock_policy != policy.lock_policy)
255  )
256  {
257  log(Error) << "You mixed incompatible connection policies for the shared output buffer of port " << port.getName() << ": "
258  << "The new connection requests a " << policy << " connection, "
259  << "but the port already has a " << buffer_policy << " buffer." << endlog();
261  }
262  }
263 
264  // Check that no shared buffer exists for all other cases...
265  } else if (buffer) {
266  // The new connection requires an unbuffered channel input or a per-connection buffer, but this port already has a shared output buffer!
267  assert(buffer->getConnPolicy());
268  ConnPolicy buffer_policy = *(buffer->getConnPolicy());
269 
270  log(Error) << "You mixed incompatible connection policies for output port " << port.getName() << ": "
271  << "The new connection requests a " << policy << " connection, "
272  << "but the port already has a " << buffer_policy << " buffer." << endlog();
274  }
275 
276  // Create buffer for PerConnection PULL connections
277  if (policy.buffer_policy == PerConnection && pull == ConnPolicy::PULL && !force_unbuffered) {
278  buffer = buildDataStorage<T>(policy, port.getLastWrittenValue());
279  if (!buffer) return base::ChannelElementBase::shared_ptr();
280  return endpoint->connectTo(buffer, policy.mandatory) ? buffer : base::ChannelElementBase::shared_ptr();
281  }
282 
283  return endpoint;
284  }
285 
301  template<typename T>
302  static base::ChannelElementBase::shared_ptr buildChannelOutput(InputPort<T>& port, ConnPolicy const& policy, T const& initial_value = T() )
303  {
304  typename internal::ConnOutputEndpoint<T>::shared_ptr endpoint = port.getEndpoint();
305 
306  // Note: PerInputPort implies PUSH and PerOutputPort implies PULL
307  bool pull = policy.pull;
308  if (policy.buffer_policy == PerInputPort) pull = ConnPolicy::PUSH;
309  if (policy.buffer_policy == PerOutputPort) pull = ConnPolicy::PULL;
310 
311  // Special case: PerInputPort
312  typename base::ChannelElement<T>::shared_ptr buffer = endpoint->getSharedBuffer();
313  if (policy.buffer_policy == PerInputPort) {
314  if (!buffer) {
315  if (endpoint->connected()) {
316  log(Error) << "You tried to create a shared input buffer connection for input port " << port.getName() << ", "
317  << "but the port already has at least one incompatible incoming connection." << endlog();
319  }
320 
321  buffer = buildDataStorage<T>(policy, initial_value);
322  if (!buffer) return base::ChannelElementBase::shared_ptr();
323 
324  // For PerInputPort connections, the buffer is installed AFTER the output endpoint!
325  if (!endpoint->connectTo(buffer)) {
327  }
328  } else {
329  // check that the buffer type is compatible to the new ConnPolicy
330  assert(buffer->getConnPolicy());
331  ConnPolicy buffer_policy = *(buffer->getConnPolicy());
332  if (
333  (buffer_policy.type != policy.type) ||
334  (buffer_policy.size != policy.size) ||
335  (buffer_policy.lock_policy != policy.lock_policy)
336  )
337  {
338  log(Error) << "You mixed incompatible connection policies for the shared input buffer of port " << port.getName() << ": "
339  << "The new connection requests a " << policy << " connection, "
340  << "but the port already has a " << buffer_policy << " buffer." << endlog();
342  }
343  }
344 
345  // Check that no shared buffer exists for all other cases...
346  } else if (buffer) {
347  // The new connection requires an unbuffered channel output or a per-connection buffer, but this port already has a shared input buffer!
348  assert(buffer->getConnPolicy());
349  ConnPolicy buffer_policy = *(buffer->getConnPolicy());
350 
351  log(Error) << "You mixed incompatible connection policies for input port " << port.getName() << ": "
352  << "The new connection requests a " << policy << " connection, "
353  << "but the port already has a " << buffer_policy << " buffer." << endlog();
355  }
356 
357  // Create buffer for PerConnection PUSH connections
358  if (policy.buffer_policy == PerConnection && pull == ConnPolicy::PUSH) {
359  buffer = buildDataStorage<T>(policy, initial_value);
360  if (!buffer) return base::ChannelElementBase::shared_ptr();
361  return buffer->connectTo(endpoint) ? buffer : base::ChannelElementBase::shared_ptr();
362  }
363 
364  return endpoint;
365  }
366 
379  static bool findSharedConnection(base::OutputPortInterface *output_port, base::InputPortInterface *input_port, ConnPolicy const& policy, SharedConnectionBase::shared_ptr &shared_connection);
380 
391  template <typename T>
393  {
394  // try to find an existing shared connection first
395  SharedConnectionBase::shared_ptr shared_connection;
396 
397  // abort if an incompatible connection has been found or one of the ports is already connected to another shared connection
398  if (findSharedConnection(output_port, input_port, policy, shared_connection) && !shared_connection) {
400  }
401 
402  // for remote input ports, and if we can derive the type from the output port, build the shared buffer at the remote side and only generate a proxy here:
403  if (input_port && !input_port->isLocal()) {
404  if (!output_port) {
405  log(Error) << "Cannot create a shared connection for a remote input port or a non-standard transport without knowing the local output port." << endlog();
407  }
408 
409  // If no existing shared connection has been found, ask the remote side to build a shared channel output and create a local proxy.
410  if (!shared_connection) {
411  base::ChannelElementBase::shared_ptr output_half = buildRemoteChannelOutput( *output_port, *input_port, policy);
412  if (!output_half) {
413  log(Error) << "Could not create a shared remote connection for input port '" << input_port->getName() << "'." << endlog();
415  }
416 
417  shared_connection = new SharedRemoteConnection<T>(policy);
418  shared_connection->connectTo(output_half, policy.mandatory);
419 
420  // ...or only ask the remote side to connect the additional input port to an existing remote shared connection
421  } else {
422 // typename SharedRemoteConnection<T>::shared_ptr shared_remote_connection = boost::dynamic_pointer_cast<SharedRemoteConnection<T> >(shared_connection);
423 
424 // if (!shared_remote_connection) {
425 // log(Error) << "Cannot create a shared connection for a remote input port because the local output port is already connected to a local shared connection." << endlog();
426 // return SharedConnectionBase::shared_ptr();
427 // }
428 
429 // if (!input_port->createConnection(shared_remote_connection, policy)) {
430  if (!input_port->createConnection(shared_connection, policy)) {
431  log(Error) << "The remote side refused to connect the input port '" << input_port->getName() << "' to the existing shared connection '" << shared_connection->getName() << "'." << endlog();
433  }
434  }
435  }
436 
437  // create a new shared connection instance
438  if (!shared_connection) {
439  RTT::OutputPort<T> *output_p = dynamic_cast<RTT::OutputPort<T> *>(output_port);
440  typename base::ChannelElement<T>::shared_ptr buffer = buildDataStorage<T>(policy, (output_p ? output_p->getLastWrittenValue() : T()));
441  if (!buffer) return SharedConnectionBase::shared_ptr();
442  shared_connection.reset(new SharedConnection<T>(buffer.get(), policy));
443  }
444 
445  return shared_connection;
446  }
447 
457  template<typename T>
458  static bool createConnection(OutputPort<T>& output_port, base::InputPortInterface& input_port, ConnPolicy const& policy)
459  {
460  PortConnectionLock lock_output_port(&output_port);
461  PortConnectionLock lock_input_port(&input_port);
462 
463  if ( !output_port.isLocal() ) {
464  log(Error) << "Need a local OutputPort to create connections." <<endlog();
465  return false;
466  }
467 
468  if (output_port.connectedTo(&input_port)) {
469  log(Info) << "OutputPort " << output_port.getName() << " is already connected to " << input_port.getName() << ", ignoring new connection." << endlog();
470  return true;
471  }
472 
473  InputPort<T>* input_p = dynamic_cast<InputPort<T>*>(&input_port);
474 
475  // Shared push connection? => forward to createAndCheckSharedConnection()
476  if (policy.buffer_policy == Shared) {
477  return createAndCheckSharedConnection(&output_port, &input_port, buildSharedConnection<T>(&output_port, &input_port, policy), policy);
478  }
479 
480  // This is the input and output channel element of the output half
482  if (input_port.isLocal() && policy.transport == 0)
483  {
484  // Local connection
485  if (!input_p)
486  {
487  log(Error) << "Port " << input_port.getName() << " is not compatible with " << output_port.getName() << endlog();
488  return false;
489  }
490 
491  // local ports, create buffer here.
492  output_half = buildChannelOutput<T>(*input_p, policy, output_port.getLastWrittenValue());
493  }
494  else
495  {
496  // if the input is not local, this is a pure remote connection,
497  // if the input *is* local, the user requested to use a different transport
498  // than plain memory, rare case, but we accept it. The unit tests use this for example
499  // to test the OOB transports.
500  if ( !input_port.isLocal() ) {
501  output_half = buildRemoteChannelOutput( output_port, input_port, policy);
502  } else if (input_p) {
503  return createOutOfBandConnection<T>( output_port, *input_p, policy);
504  } else {
505  log(Error) << "Port " << input_port.getName() << " is not compatible with " << output_port.getName() << endlog();
506  return false;
507  }
508  }
509 
510  if (!output_half)
511  return false;
512 
513  // Since output is local, buildChannelInput is local as well.
514  // This this the input channel element of the whole connection
516  channel_input = buildChannelInput<T>(output_port, policy);
517 
518  if (!channel_input) {
519  output_half->disconnect(true);
520  return false;
521  }
522 
523  // NOTE: channel_input and output_half are not yet connected!
524  return createAndCheckConnection(output_port, input_port, channel_input, output_half, policy);
525  }
526 
534  template<class T>
535  static bool createStream(OutputPort<T>& output_port, ConnPolicy const& policy)
536  {
537  PortConnectionLock lock_output_port(&output_port);
538 
539  StreamConnID *sid = new StreamConnID(policy.name_id);
540  // Stream channel inputs are always unbuffered (push). It's the transport that has to add a buffer element if required.
541  RTT::base::ChannelElementBase::shared_ptr chan = buildChannelInput( output_port, policy, /* force_unbuffered = */ true );
542  if (!chan) return false;
543  if (!bool(createAndCheckStream(output_port, policy, chan, sid))) {
544  chan->disconnect(false);
545  return false;
546  }
547  return true;
548  }
549 
557  template<class T>
558  static bool createStream(InputPort<T>& input_port, ConnPolicy const& policy)
559  {
560  PortConnectionLock lock_input_port(&input_port);
561 
562  StreamConnID *sid = new StreamConnID(policy.name_id);
563  RTT::base::ChannelElementBase::shared_ptr outhalf = buildChannelOutput( input_port, policy );
564  if (!outhalf) return false;
565  if (!bool(createAndCheckStream(input_port, policy, outhalf, sid))) {
566  outhalf->disconnect(true);
567  return false;
568  }
569  return true;
570  }
571 
572  static bool createSharedConnection(base::OutputPortInterface* output_port, base::InputPortInterface* input_port, SharedConnectionBase::shared_ptr shared_connection, ConnPolicy const& policy);
573 
574  protected:
575  static bool createAndCheckConnection(base::OutputPortInterface& output_port, base::InputPortInterface& input_port, base::ChannelElementBase::shared_ptr channel_input, base::ChannelElementBase::shared_ptr channel_output, ConnPolicy const& policy);
576 
577  static bool createAndCheckSharedConnection(base::OutputPortInterface* output_port, base::InputPortInterface* input_port, SharedConnectionBase::shared_ptr shared_connection, ConnPolicy const& policy);
578 
579  static base::ChannelElementBase::shared_ptr createAndCheckStream(base::OutputPortInterface& output_port, ConnPolicy const& policy, base::ChannelElementBase::shared_ptr channel_input, StreamConnID* conn_id);
580 
581  static base::ChannelElementBase::shared_ptr createAndCheckStream(base::InputPortInterface& input_port, ConnPolicy const& policy, base::ChannelElementBase::shared_ptr channel_output, StreamConnID* conn_id);
582 
583  static base::ChannelElementBase::shared_ptr buildRemoteChannelOutput(base::OutputPortInterface& output_port, base::InputPortInterface& input_port, ConnPolicy const& policy);
584 
592  template<class T>
593  static bool createOutOfBandConnection(OutputPort<T>& output_port, InputPort<T>& input_port, ConnPolicy const& policy) {
594  // constructs an out-of-band channel:
595  // output_port -> channel_input -> stream_input -> (out-of-band transport of data) -> stream_output -> channel_output -> input_port
596  // |-- (direct connection for coordination) --^
597  //
598 
599  // Stream channel inputs are always unbuffered (push). It's the transport that has to add a buffer element if required.
600  RTT::base::ChannelElementBase::shared_ptr channel_input = buildChannelInput( output_port, policy, /* force_unbuffered = */ true );
601  if (!channel_input) return false;
602 
603  RTT::base::ChannelElementBase::shared_ptr stream_input = createAndCheckStream(output_port, policy, channel_input, new StreamConnID(policy.name_id));
604  if (!stream_input) return false;
605 
606  RTT::base::ChannelElementBase::shared_ptr channel_output = ConnFactory::buildChannelOutput<T>(input_port, policy, output_port.getLastWrittenValue());
607  if (!channel_output) return false;
608 
609  RTT::base::ChannelElementBase::shared_ptr stream_output = createAndCheckStream(input_port, policy, channel_output, new StreamConnID(policy.name_id));
610  if (!stream_output) return false;
611 
612  return stream_input->getOutputEndPoint()->connectTo(stream_output->getInputEndPoint(), policy.mandatory);
613  }
614 
615  };
616 
617  typedef boost::shared_ptr<ConnFactory> ConnFactoryPtr;
618 
619 }}
620 
621 #endif
622 
boost::intrusive_ptr< ChannelElement< T > > shared_ptr
virtual bool createConnection(internal::SharedConnectionBase::shared_ptr shared_connection, ConnPolicy const &policy=ConnPolicy())
boost::intrusive_ptr< SharedConnectionBase > shared_ptr
base::PortInterface const * ptr
Definition: ConnFactory.hpp:69
virtual bool isLocal() const
virtual ConnID * clone() const
Definition: ConnFactory.cpp:57
static base::ChannelElementBase::shared_ptr buildChannelOutput(InputPort< T > &port, ConnPolicy const &policy, T const &initial_value=T())
boost::shared_ptr< DataObjectInterface< T > > shared_ptr
static const int CIRCULAR_BUFFER
Definition: ConnPolicy.hpp:113
boost::intrusive_ptr< ConnInputEndpoint< T > > shared_ptr
virtual base::ChannelElement< T >::shared_ptr getSharedBuffer()
virtual const ConnPolicy * getConnPolicy() const
static const bool PULL
Definition: ConnPolicy.hpp:120
const std::string & getName() const
virtual bool isSameID(ConnID const &id) const
Definition: ConnFactory.cpp:49
static const int LOCKED
Definition: ConnPolicy.hpp:116
virtual internal::ConnInputEndpoint< T > * getEndpoint() const
Definition: OutputPort.hpp:338
static const bool PUSH
Definition: ConnPolicy.hpp:119
A class which provides unprotected (not thread-safe) access to one typed element of data...
static const int DATA
Definition: ConnPolicy.hpp:111
virtual internal::ConnOutputEndpoint< T > * getEndpoint() const
Definition: InputPort.hpp:229
boost::shared_ptr< ConnFactory > ConnFactoryPtr
StreamConnID(const std::string &name)
Definition: ConnFactory.hpp:82
static bool createStream(InputPort< T > &input_port, ConnPolicy const &policy)
static base::ChannelElement< T > * buildDataStorage(ConnPolicy const &policy, const T &initial_value=T())
virtual bool connectTo(ChannelElementBase::shared_ptr const &output, bool mandatory=true)
virtual bool connectedTo(PortInterface *port)
This DataObject is a Lock-Free implementation, such that reads and writes can happen concurrently wit...
static bool createStream(OutputPort< T > &output_port, ConnPolicy const &policy)
static bool createOutOfBandConnection(OutputPort< T > &output_port, InputPort< T > &input_port, ConnPolicy const &policy)
static const int LOCK_FREE
Definition: ConnPolicy.hpp:117
boost::intrusive_ptr< ChannelElementBase > shared_ptr
A class which provides locked/protected access to one typed element of data.
virtual base::ChannelElement< T >::shared_ptr getSharedBuffer() const
Definition: OutputPort.hpp:344
LocalConnID(base::PortInterface const *obj)
Definition: ConnFactory.hpp:70
static SharedConnectionBase::shared_ptr buildSharedConnection(OutputPort< T > *output_port, base::InputPortInterface *input_port, ConnPolicy const &policy)
static const int UNSYNC
Definition: ConnPolicy.hpp:115
boost::intrusive_ptr< ConnOutputEndpoint< T > > shared_ptr
static const int BUFFER
Definition: ConnPolicy.hpp:112
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
static base::ChannelElementBase::shared_ptr buildChannelInput(OutputPort< T > &port, ConnPolicy const &policy, bool force_unbuffered=false)
std::string name_id
Definition: ConnPolicy.hpp:256
T getLastWrittenValue() const
Definition: OutputPort.hpp:173
static Logger & log()
Definition: Logger.hpp:350
static bool createConnection(OutputPort< T > &output_port, base::InputPortInterface &input_port, ConnPolicy const &policy)
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
boost::shared_ptr< BufferInterface< T > > shared_ptr


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:32