Orocos Real-Time Toolkit  2.9.0
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  using namespace detail;
49 
50 
52  {
53  public:
54  E(base::DataSourceBase::shared_ptr op) : s(), b(), mop(op), orp(0) {}
55 
56  ~E() {
57  // force synchronisation in case we are the last SendHandleC. We may not cleanup mop (holds data!), until the op
58  // completed or failed.
59  // Reduce refcount on mopkeeper
60  mopkeeper.reset();
61  }
62 
76 
82  {
88  if (ms && autocollect) {
89  mb->set(true); // blocking
90  try { // the evaluated function may throw
91  ms->evaluate();
92  } catch (std::exception&) {
93  }
94  }
95  }
96  };
97 
98  boost::shared_ptr<OperationKeeper> mopkeeper;
99 
104  };
105 
106 
107 
109  {
110  public:
112  std::string mname;
113  std::vector<DataSourceBase::shared_ptr> args;
117 
118  void checkAndCreate() {
119  Logger::In in("SendHandleC");
120  if ( mofp ) {
121  size_t sz = mofp->collectArity();
122  if ( sz == args.size() ) {
123  // insert the send handle first.
124  args.insert( args.begin(), msh );
125  // may throw or return nill
126  s = boost::dynamic_pointer_cast<DataSource<SendStatus> >( mofp->produceCollect(args, blocking ) );
127  args.clear();
128  if ( !s ) {
129  log(Error) << "Failed to produce collector for "<< mname << " with " << sz << " arguments." << endlog();
130  return;
131  }
132  }
133  }
134  }
135 
137  {
138  this->args.push_back( na );
139  this->checkAndCreate();
140  }
141 
142  D( base::DataSourceBase::shared_ptr sh, OperationInterfacePart* ofp, const std::string& name)
143  : mofp(ofp), mname(name), s(), msh(sh), blocking( new ValueDataSource<bool>(false) )
144  {
145  this->checkAndCreate();
146  }
147 
148  D(const D& other)
149  : mofp(other.mofp), mname(other.mname),
150  args( other.args ), s( other.s ), msh(other.msh), blocking(new ValueDataSource<bool>(false))
151  {
152  }
153 
154  ~D()
155  {
156  }
157 
158  };
159 
161  : d(0), e( new E(0) )
162  {
163  }
164 
166  : d( ofp ? new D( sh, ofp, name ) : 0 ), e( new E(op) )
167  {
168  if ( d->s ) {
169  e->s = d->s;
170  e->b = d->blocking;
171  e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
172  delete d;
173  d = 0;
174  }
175  this->e->orp = ofp;
176  }
177 
179  : d( other.d ? new D(*other.d) : 0 ), e( new E(*other.e) )
180  {
181  }
182 
184  {
185  if ( &other == this )
186  return *this;
187  delete d;
188  d = ( other.d ? new D(*other.d) : 0 );
189  e->s = other.e->s;
190  e->b = other.e->b;
191  e->mop = other.e->mop;
192  e->mopkeeper = other.e->mopkeeper;
193  e->orp = other.e->orp;
194  return *this;
195  }
196 
198  {
199  delete d;
200  delete e;
201  }
202 
204  {
205  if (d)
206  d->newarg( a );
207  else {
208  Logger::log() <<Logger::Warning << "Extra argument discarded for SendHandleC."<<Logger::endl;
209  }
210  if ( d && d->s ) {
211  e->s = d->s;
212  e->b = d->blocking;
213  e->orp = d->mofp;
214  e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
215  delete d;
216  d = 0;
217  }
218  return *this;
219  }
220 
222  if (e->s) {
223  e->b->set(true); // blocking
224  e->s->evaluate();
225  return e->s->value();
226  }
227  else {
228  Logger::log() <<Logger::Error << "collect() called on incomplete SendHandleC."<<Logger::endl;
229  if (d) {
230  size_t sz;
231  sz = d->mofp->collectArity();
232  Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
233  Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
234  }
235  }
236  return SendFailure;
237  }
238 
240  if (e->s) {
241  e->b->set(false); // non blocking
242  // does the send.
243  e->s->evaluate();
244  // pass on handle.
245  return e->s->value();
246  }
247  else {
248  Logger::log() <<Logger::Error << "collectIfDone() called on incomplete SendHandleC."<<Logger::endl;
249  if (d) {
250  size_t sz;
251  sz = d->mofp->collectArity();
252  Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
253  Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
254  }
255  }
256  return SendFailure;
257  }
258 
259  bool SendHandleC::ready() const
260  {
261  return e->s != 0;
262  }
263 
264  void SendHandleC::setAutoCollect(bool on_off) {
265  if (e->mopkeeper)
266  e->mopkeeper->autocollect = on_off;
267  }
268 
269  void SendHandleC::check() {
270  if (d) {
271  // something went wrong, let producer throw
272  if (d->mofp)
273  DataSourceBase::shared_ptr dummy = d->mofp->produceCollect( d->args, d->blocking );
274  else
275  throw invalid_handle_exception();
276  }
277  }
278 
279 
281 
282  OperationInterfacePart* SendHandleC::getOrp() { return e->orp; }
283 }
D(base::DataSourceBase::shared_ptr sh, OperationInterfacePart *ofp, const std::string &name)
DataSource is a base class representing a generic way to read data of type T.
Definition: DataSource.hpp:94
void newarg(DataSourceBase::shared_ptr na)
SendHandleC()
The default constructor.
internal::DataSource< SendStatus >::shared_ptr s
This data source will do a collect/collectIfDone when being evaluated().
Definition: SendHandleC.cpp:67
OperationKeeper(DataSource< SendStatus >::shared_ptr s, AssignableDataSource< bool >::shared_ptr b)
Definition: SendHandleC.cpp:86
base::DataSourceBase::shared_ptr getSendHandleDataSource()
Get the contained data source for send handle.
DataSourceBase::shared_ptr msh
SendHandleC & operator=(const SendHandleC &other)
A SendHandleC is assignable.
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 ...
internal::AssignableDataSource< bool >::shared_ptr b
Stores the blocking/non blocking flag for collect/collectIfDone.
Definition: SendHandleC.cpp:71
OperationInterfacePart * orp
Stores the OperationInterfacePart pointer contained in this SendHandle.
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 ...
SendHandleC & arg(base::DataSourceBase::shared_ptr a)
Add a datasource argument to the SendHandle.
E(base::DataSourceBase::shared_ptr op)
Definition: SendHandleC.cpp:54
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
A template-less SendHandle manager.
Definition: SendHandleC.hpp:61
base::DataSourceBase::shared_ptr mop
Stores the operation in order to avoid its premature destruction.
Definition: SendHandleC.cpp:75
Returned when the result of the send() could not be collected.
Definition: SendStatus.hpp:55
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
OperationInterfacePart * mofp
SendStatus collectIfDone()
Collect the contained method.
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...
AssignableDataSource< bool >::shared_ptr blocking
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
boost::shared_ptr< OperationKeeper > mopkeeper
Definition: SendHandleC.cpp:98
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.
AssignableDataSource< bool >::shared_ptr mb
Definition: SendHandleC.cpp:84
This is a custom deleter that blocks on an asynchronous operation.
Definition: SendHandleC.cpp:81
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.
DataSource< SendStatus >::shared_ptr ms
Definition: SendHandleC.cpp:83
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.
std::vector< DataSourceBase::shared_ptr > args
D(const D &other)
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:52
virtual bool evaluate() const
Force an evaluation of the DataSourceBase.
Definition: DataSource.inl:52
OperationInterfacePart * getOrp()
Get the contained OperationInterfacePart for SendHandle.
A simple, yet very useful DataSource, which keeps a value, and returns it in its get() method...
Definition: DataSources.hpp:60
DataSource< SendStatus >::shared_ptr s