Orocos Real-Time Toolkit  2.8.3
SendHandleC.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 SendHandleC.cpp
3 
4  SendHandleC.cpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.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 #include "SendHandleC.hpp"
40 #include "../FactoryExceptions.hpp"
41 #include "DataSourceCommand.hpp"
42 #include "../Service.hpp"
43 #include "../Logger.hpp"
44 #include "Exceptions.hpp"
45 #include <vector>
46 
47 namespace RTT
48 { namespace internal {
49 
50  using namespace detail;
51 
52 
54  {
55  public:
56  E(base::DataSourceBase::shared_ptr op) : s(), b(), mop(op), orp(0) {}
57 
58  ~E() {
59  // force synchronisation in case we are the last SendHandleC. We may not cleanup mop (holds data!), until the op
60  // completed or failed.
61  // Reduce refcount on mopkeeper
62  mopkeeper.reset();
63  }
64 
78 
84  {
90  if (ms && autocollect) {
91  mb->set(true); // blocking
92  try { // the evaluated function may throw
93  ms->evaluate();
94  } catch (std::exception&) {
95  }
96  }
97  }
98  };
99 
100  boost::shared_ptr<OperationKeeper> mopkeeper;
101 
106  };
107 
108 
109 
111  {
112  public:
114  std::string mname;
115  std::vector<DataSourceBase::shared_ptr> args;
119 
120  void checkAndCreate() {
121  Logger::In in("SendHandleC");
122  if ( mofp ) {
123  size_t sz = mofp->collectArity();
124  if ( sz == args.size() ) {
125  // insert the send handle first.
126  args.insert( args.begin(), msh );
127  // may throw or return nill
128  s = boost::dynamic_pointer_cast<DataSource<SendStatus> >( mofp->produceCollect(args, blocking ) );
129  args.clear();
130  if ( !s ) {
131  log(Error) << "Failed to produce collector for "<< mname << " with " << sz << " arguments." << endlog();
132  return;
133  }
134  }
135  }
136  }
137 
139  {
140  this->args.push_back( na );
141  this->checkAndCreate();
142  }
143 
144  D( base::DataSourceBase::shared_ptr sh, OperationInterfacePart* ofp, const std::string& name)
145  : mofp(ofp), mname(name), s(), msh(sh), blocking( new ValueDataSource<bool>(false) )
146  {
147  this->checkAndCreate();
148  }
149 
150  D(const D& other)
151  : mofp(other.mofp), mname(other.mname),
152  args( other.args ), s( other.s ), msh(other.msh), blocking(new ValueDataSource<bool>(false))
153  {
154  }
155 
156  ~D()
157  {
158  }
159 
160  };
161 
163  : d(0), e( new E(0) )
164  {
165  }
166 
168  : d( ofp ? new D( sh, ofp, name ) : 0 ), e( new E(op) )
169  {
170  if ( d->s ) {
171  e->s = d->s;
172  e->b = d->blocking;
173  e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
174  delete d;
175  d = 0;
176  }
177  this->e->orp = ofp;
178  }
179 
181  : d( other.d ? new D(*other.d) : 0 ), e( new E(*other.e) )
182  {
183  }
184 
186  {
187  if ( &other == this )
188  return *this;
189  delete d;
190  d = ( other.d ? new D(*other.d) : 0 );
191  e->s = other.e->s;
192  e->b = other.e->b;
193  e->mop = other.e->mop;
194  e->mopkeeper = other.e->mopkeeper;
195  e->orp = other.e->orp;
196  return *this;
197  }
198 
200  {
201  delete d;
202  delete e;
203  }
204 
206  {
207  if (d)
208  d->newarg( a );
209  else {
210  Logger::log() <<Logger::Warning << "Extra argument discarded for SendHandleC."<<Logger::endl;
211  }
212  if ( d && d->s ) {
213  e->s = d->s;
214  e->b = d->blocking;
215  e->orp = d->mofp;
216  e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
217  delete d;
218  d = 0;
219  }
220  return *this;
221  }
222 
224  if (e->s) {
225  e->b->set(true); // blocking
226  e->s->evaluate();
227  return e->s->value();
228  }
229  else {
230  Logger::log() <<Logger::Error << "collect() called on incomplete SendHandleC."<<Logger::endl;
231  if (d) {
232  size_t sz;
233  sz = d->mofp->collectArity();
234  Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
235  Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
236  }
237  }
238  return SendFailure;
239  }
240 
242  if (e->s) {
243  e->b->set(false); // non blocking
244  // does the send.
245  e->s->evaluate();
246  // pass on handle.
247  return e->s->value();
248  }
249  else {
250  Logger::log() <<Logger::Error << "collectIfDone() called on incomplete SendHandleC."<<Logger::endl;
251  if (d) {
252  size_t sz;
253  sz = d->mofp->collectArity();
254  Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
255  Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
256  }
257  }
258  return SendFailure;
259  }
260 
261  bool SendHandleC::ready() const
262  {
263  return e->s != 0;
264  }
265 
266  void SendHandleC::setAutoCollect(bool on_off) {
267  if (e->mopkeeper)
268  e->mopkeeper->autocollect = on_off;
269  }
270 
272  if (d) {
273  // something went wrong, let producer throw
274  if (d->mofp)
276  else
277  throw invalid_handle_exception();
278  }
279  }
280 
281 
283 
285 
286 }}
base::DataSourceBase::shared_ptr mop
Stores the operation in order to avoid its premature destruction.
Definition: SendHandleC.cpp:77
internal::DataSource< SendStatus >::shared_ptr s
This data source will do a collect/collectIfDone when being evaluated().
Definition: SendHandleC.cpp:69
DataSource is a base class representing a generic way to read data of type T.
Definition: DataSource.hpp:94
SendHandleC()
The default constructor.
E(base::DataSourceBase::shared_ptr op)
Definition: SendHandleC.cpp:56
D(base::DataSourceBase::shared_ptr sh, OperationInterfacePart *ofp, const std::string &name)
std::vector< DataSourceBase::shared_ptr > args
OperationInterfacePart * getOrp()
Get the contained OperationInterfacePart for SendHandle.
OperationInterfacePart * orp
Stores the OperationInterfacePart pointer contained in this SendHandle.
SendHandleC & operator=(const SendHandleC &other)
A SendHandleC is assignable.
DataSource< SendStatus >::shared_ptr s
virtual void set(param_t t)=0
Set this DataSource with a value.
static std::ostream & nl(std::ostream &__os)
Insert a newline &#39; &#39; in the ostream.
Definition: Logger.cpp:373
When Orocos is compiled without exceptions (define ORO_EMBEDDED), the functions which would throw an ...
AssignableDataSource< bool >::shared_ptr blocking
This is a custom deleter that blocks on an asynchronous operation.
Definition: SendHandleC.cpp:83
void setAutoCollect(bool on_off)
When set to &#39;on&#39;, the destruction of this SendHandleC will cause a call to collect() before all data ...
SendStatus collect()
Collect the contained method.
Exception thrown when a factory is requested to create an object with an invalid SendHandle.
SendStatus
Returns the status of a send() or collect() invocation.
Definition: SendStatus.hpp:53
DataSourceBase::shared_ptr msh
OperationInterfacePart * mofp
SendHandleC & arg(base::DataSourceBase::shared_ptr a)
Add a datasource argument to the SendHandle.
A template-less SendHandle manager.
Definition: SendHandleC.hpp:61
base::DataSourceBase::shared_ptr getSendHandleDataSource()
Get the contained data source for send handle.
Returned when the result of the send() could not be collected.
Definition: SendStatus.hpp:55
AssignableDataSource< bool >::shared_ptr mb
Definition: SendHandleC.cpp:86
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
SendStatus collectIfDone()
Collect the contained method.
internal::AssignableDataSource< bool >::shared_ptr b
Stores the blocking/non blocking flag for collect/collectIfDone.
Definition: SendHandleC.cpp:73
bool ready() const
Returns true if this handle is ready for execution.
This class defines the interface for creating operation objects without using C++ templates...
void newarg(DataSourceBase::shared_ptr na)
boost::intrusive_ptr< DataSource< T > > shared_ptr
Definition: DataSource.hpp:115
boost::intrusive_ptr< AssignableDataSource< T > > shared_ptr
Use this type to store a pointer to an AssignableDataSource.
Definition: DataSource.hpp:198
virtual base::DataSourceBase::shared_ptr produceCollect(const std::vector< base::DataSourceBase::shared_ptr > &args, internal::DataSource< bool >::shared_ptr blocking) const =0
Create a DataSource for collecting the results of a Send.
DataSource< SendStatus >::shared_ptr ms
Definition: SendHandleC.cpp:85
A DataSource which has set() methods.
Definition: DataSource.hpp:184
virtual unsigned int collectArity() const =0
Returns the number of collectable arguments of this operation&#39;s function.
Notify the Logger in which &#39;module&#39; the message occured.
Definition: Logger.hpp:159
static Logger & log()
As Instance(), but more userfriendly.
Definition: Logger.cpp:117
void check()
Checks if this handle is ready for collecting, will throw if not so.
virtual result_t value() const =0
Return the result of the last evaluate() function.
boost::shared_ptr< OperationKeeper > mopkeeper
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
virtual bool evaluate() const
Force an evaluation of the DataSourceBase.
Definition: DataSource.inl:52
A simple, yet very useful DataSource, which keeps a value, and returns it in its get() method...
Definition: DataSources.hpp:60
OperationKeeper(DataSource< SendStatus >::shared_ptr s, AssignableDataSource< bool >::shared_ptr b)
Definition: SendHandleC.cpp:88