[PATCH] operations: add synchronous operation factories

This patch makes it possible to register an operation as synchronous.
The port services use this in order to install a reduced version of
their read/write/last operations, which are only meant for in-component
thread, ie synchronous, usage.

Synchronous operations are not exported throught the CORBA layer.

This solution is here to reduce compilation time of typekits mainly,
and partly because reading/writing ports should only be done by the
component itself.

If we find a better solution, this approach may be deprecated.

In-process asynchronous usage of the operation will still be tolerated,
since it's only the Service interface that is limited, not the Operation
object itself.

Initial patch suggested by Sylvain Joyeux and worked out by Peter Soetens.

Signed-off-by: Peter Soetens <peter [..] ...>
---
rtt/InputPort.hpp | 2 +-
rtt/OutputPort.hpp | 4 +-
rtt/base/PortInterface.cpp | 6 +-
rtt/interface/FactoryExceptions.cpp | 11 ++++
rtt/interface/FactoryExceptions.hpp | 13 ++++
rtt/interface/OperationRepository.cpp | 12 ++++
rtt/interface/OperationRepository.hpp | 12 ++++
rtt/interface/OperationRepositoryPart.hpp | 6 ++-
rtt/interface/ServiceProvider.hpp | 41 +++++++++++++
rtt/internal/MethodC.cpp | 14 ++++-
rtt/internal/OperationRepositoryPartFused.hpp | 76 +++++++++++++++++++++++++
rtt/scripting/ExpressionParser.cpp | 6 ++-
rtt/transports/corba/OperationRepositoryI.cpp | 34 ++++++++---
13 files changed, 217 insertions(+), 20 deletions(-)

diff --git a/rtt/InputPort.hpp b/rtt/InputPort.hpp
index b655dd6..7585c4e 100644
--- a/rtt/InputPort.hpp
+++ b/rtt/InputPort.hpp
@@ -160,7 +160,7 @@ namespace RTT
// Force resolution on the overloaded write method
typedef FlowStatus (InputPort<T>::*ReadSample)(typename base::ChannelElement<T>::reference_t);
ReadSample read_m = &InputPort<T>::read;
- object->addOperation("read", read_m, this).doc("Reads a sample from the port.").arg("sample", "");
+ object->addSynchronousOperation("read", read_m, this).doc("Reads a sample from the port.").arg("sample", "");
return object;
}
};
diff --git a/rtt/OutputPort.hpp b/rtt/OutputPort.hpp
index 87a77fb..ad54e72 100644
--- a/rtt/OutputPort.hpp
+++ b/rtt/OutputPort.hpp
@@ -302,8 +302,8 @@ namespace RTT
WriteSample write_m = &OutputPort::write;
typedef T (OutputPort<T>::*LastSample)() const;
LastSample last_m = &OutputPort::getLastWrittenValue;
- object->addOperation("write", write_m, this).doc("Writes a sample on the port.").arg("sample", "");
- object->addOperation("last", last_m, this).doc("Returns last written value to this port.");
+ object->addSynchronousOperation("write", write_m, this).doc("Writes a sample on the port.").arg("sample", "");
+ object->addSynchronousOperation("last", last_m, this).doc("Returns last written value to this port.");
return object;
}
};
diff --git a/rtt/base/PortInterface.cpp b/rtt/base/PortInterface.cpp
index a7bc971..6d454eb 100644
--- a/rtt/base/PortInterface.cpp
+++ b/rtt/base/PortInterface.cpp
@@ -75,10 +75,10 @@ ServiceProvider* PortInterface::createPortObject()
{
#ifndef ORO_EMBEDDED
ServiceProvider* to = new ServiceProvider( this->getName(), iface->getParent() );
- to->addOperation( "name",&PortInterface::getName, this).doc(
+ to->addSynchronousOperation( "name",&PortInterface::getName, this).doc(
"Returns the port name.");
- to->addOperation("connected", &PortInterface::connected, this).doc("Check if this port is connected and ready for use.");
- to->addOperation("disconnect", &PortInterface::disconnect, this).doc("Disconnects this port from any connection it is part of.");
+ to->addSynchronousOperation("connected", &PortInterface::connected, this).doc("Check if this port is connected and ready for use.");
+ to->addSynchronousOperation("disconnect", &PortInterface::disconnect, this).doc("Disconnects this port from any connection it is part of.");
return to;
#else
return 0;
diff --git a/rtt/interface/FactoryExceptions.cpp b/rtt/interface/FactoryExceptions.cpp
index c5dbdee..4c068f2 100644
--- a/rtt/interface/FactoryExceptions.cpp
+++ b/rtt/interface/FactoryExceptions.cpp
@@ -65,6 +65,17 @@ namespace RTT {
return whatstr.c_str();
}

+ no_asynchronous_operation_exception::no_asynchronous_operation_exception(std::string const& what)
+ : whatstr(what)
+ {
+ }
+
+ no_asynchronous_operation_exception::~no_asynchronous_operation_exception() throw() {}
+
+ const char* no_asynchronous_operation_exception::what() const throw() {
+ return whatstr.c_str();
+ }
+
wrong_number_of_args_exception::wrong_number_of_args_exception( int w, int r )
: wanted( w ), received( r )
{
diff --git a/rtt/interface/FactoryExceptions.hpp b/rtt/interface/FactoryExceptions.hpp
index 4f1ac7f..1403f89 100644
--- a/rtt/interface/FactoryExceptions.hpp
+++ b/rtt/interface/FactoryExceptions.hpp
@@ -110,6 +110,19 @@ namespace RTT
virtual const char* what() const throw();
};

+ /**
+ * Exception thrown when a factory is requested to
+ * produce an asynchronous object while it is not available for that operation.
+ */
+ struct RTT_EXPORT no_asynchronous_operation_exception
+ : public std::exception
+ {
+ std::string whatstr;
+ no_asynchronous_operation_exception( const std::string& what );
+ ~no_asynchronous_operation_exception() throw();
+ virtual const char* what() const throw();
+ };
+
/**
* Exception thrown when a factory is requested to
* create an object, and one of the arguments needed to
diff --git a/rtt/interface/OperationRepository.cpp b/rtt/interface/OperationRepository.cpp
index 8eb4ff9..b9d4bbc 100644
--- a/rtt/interface/OperationRepository.cpp
+++ b/rtt/interface/OperationRepository.cpp
@@ -52,6 +52,18 @@ int OperationRepository::getCollectArity(const std::string& name) const
return i->second->collectArity();
}

+bool OperationRepository::isSynchronous(const std::string& name) const
+{
+ if (!hasMember(name))
+ return false;
+ try {
+ produceHandle(name);
+ } catch(...) {
+ return true;
+ }
+ return false;
+}
+
base::DataSourceBase::shared_ptr OperationRepository::produce(const std::string& name, const Arguments& args, ExecutionEngine* caller) const
{
map_t::const_iterator i = data.find(name);
diff --git a/rtt/interface/OperationRepository.hpp b/rtt/interface/OperationRepository.hpp
index daf1378..3ff4dc9 100644
--- a/rtt/interface/OperationRepository.hpp
+++ b/rtt/interface/OperationRepository.hpp
@@ -70,6 +70,13 @@ namespace RTT
int getCollectArity(const std::string& name) const;

/**
+ * Query if a given operation is limited to sychronous invocation (own component thread)
+ * only.
+ * @return false if name not found or a normal operation, true if name exists but is synchronous.
+ */
+ bool isSynchronous(const std::string& name) const;
+
+ /**
* Produce a DataSource that call()s an operation.
* The DataSource will return the result of call().
*
@@ -94,6 +101,8 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
+ *
*/
base::DataSourceBase::shared_ptr produceSend(const std::string& name, const Arguments& args, ExecutionEngine* caller) const;

@@ -109,6 +118,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
base::DataSourceBase::shared_ptr produceHandle(const std::string& name) const;

@@ -126,6 +136,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
base::DataSourceBase::shared_ptr produceCollect(const std::string& name, const Arguments& args, internal::DataSource<bool>::shared_ptr blocking) const;

@@ -142,6 +153,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
Handle produceSignal(const std::string& name, base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args) const;

diff --git a/rtt/interface/OperationRepositoryPart.hpp b/rtt/interface/OperationRepositoryPart.hpp
index cdff4d3..67dc6fa 100644
--- a/rtt/interface/OperationRepositoryPart.hpp
+++ b/rtt/interface/OperationRepositoryPart.hpp
@@ -108,6 +108,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
virtual base::DataSourceBase::shared_ptr produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller) const = 0;

@@ -117,6 +118,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
virtual base::DataSourceBase::shared_ptr produceHandle() const = 0;

@@ -132,6 +134,7 @@ namespace RTT
* @throw wrong_number_of_args_exception
* @throw wrong_types_of_args_exception
* @throw name_not_found_exception
+ * @throw no_asynchronous_operation_exception
*/
virtual base::DataSourceBase::shared_ptr produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, internal::DataSource<bool>::shared_ptr blocking) const = 0;

@@ -141,7 +144,8 @@ namespace RTT
* @param func The function to execute
* @param args The data sources to fill in with the arguments the operation was given.
* The number of elements and their type must match the signature of the operation.
- * @return
+ * @return A valid Signal Handle if the arguments were valid.
+ * @throw no_asynchronous_operation_exception
*/
virtual Handle produceSignal( base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args) const = 0;

diff --git a/rtt/interface/ServiceProvider.hpp b/rtt/interface/ServiceProvider.hpp
index 16e5ce8..fe1c0bf 100644
--- a/rtt/interface/ServiceProvider.hpp
+++ b/rtt/interface/ServiceProvider.hpp
@@ -225,6 +225,23 @@ namespace RTT
}

/**
+ * Add an operation object to the interface. This version exports an
+ * existing Operation object to the synchronous interface of the component
+ *
+ * @param op The operation object to add.
+ *
+ * @return The given parameter \a op
+ */
+ template<class Signature>
+ Operation<Signature>& addSynchronousOperation( Operation<Signature>& op )
+ {
+ if ( this->addLocalOperation( op ) == false )
+ return op;
+ this->add( op.getName(), new internal::SynchronousOperationRepositoryPartFused<Signature>( &op ) );
+ return op;
+ }
+
+ /**
* Add an operation to the interface by means of a function.
* The function \a func may be a \a free function (a 'C' function) or
* an object member function, in which case serv may not be null
@@ -249,6 +266,30 @@ namespace RTT
}

/**
+ * Add an operation to the synchronous interface by means of a function.
+ * The function \a func may be a \a free function (a 'C' function) or
+ * an object member function, in which case serv may not be null
+ *
+ * @param name The name of the new operation
+ * @param func A pointer to a function, for example, &foo ('C' function) or &Bar::foo (C++ class function).
+ * @param serv A pointer to the object that will execute the function in case of a C++ class function,
+ * or zero ('0') in case of a 'C' function.
+ * @param et The ExecutionThread choice: will the owning TaskContext of this service execute
+ * the function \a func in its own thread, or will the client's thread (the caller) execute \a func ?
+ *
+ * @return A newly created operation object, which you may further document or query.
+ */
+ template<class Func, class Service>
+ Operation< typename internal::GetSignature<Func>::Signature >&
+ addSynchronousOperation( const std::string name, Func func, Service* serv = 0, ExecutionThread et = ClientThread )
+ {
+ typedef typename internal::GetSignature<Func>::Signature Signature;
+ Operation<Signature>* op = new Operation<Signature>(name, func, serv, et);
+ ownedoperations.push_back(op);
+ return addSynchronousOperation( *op );
+ }
+
+ /**
* For internal use only. The pointer of the object of which a member function
* must be invoked is stored in a internal::DataSource such that the pointer can change
* during program execution. Required in scripting for state machines.
diff --git a/rtt/internal/MethodC.cpp b/rtt/internal/MethodC.cpp
index 0859bdf..d54a02f 100644
--- a/rtt/internal/MethodC.cpp
+++ b/rtt/internal/MethodC.cpp
@@ -66,7 +66,11 @@ namespace RTT {
if ( sz == args.size() ) {
// may throw or return nill
m = ofp->produce(args, caller );
- s = ofp->produceSend(args, caller );
+ try {
+ s = ofp->produceSend(args, caller );
+ } catch( no_asynchronous_operation_exception const& e) {
+ // leave s empty.
+ }
args.clear();
if ( !m )
return;
@@ -231,8 +235,14 @@ namespace RTT {
}

SendHandleC MethodC::send() {
+ DataSourceBase::shared_ptr h;
+ try {
+ h = ofp->produceHandle();
+ } catch( no_asynchronous_operation_exception const& nao) {
+ log(Error) <<"MethodC::send(): Can not send a synchronous operation." << endlog();
+ return SendHandleC();
+ }
if (s) {
- DataSourceBase::shared_ptr h = ofp->produceHandle();
// evaluate and copy result of s to handle and pass handle to SendHandleC.
#ifndef NDEBUG
bool result =
diff --git a/rtt/internal/OperationRepositoryPartFused.hpp b/rtt/internal/OperationRepositoryPartFused.hpp
index 898d543..ca8cc3e 100644
--- a/rtt/internal/OperationRepositoryPartFused.hpp
+++ b/rtt/internal/OperationRepositoryPartFused.hpp
@@ -145,6 +145,82 @@ namespace RTT
}
};

+ /**
+ * OperationRepositoryPart implementation that only provides synchronous
+ * access to an operation. Only produce() can be called, the others will
+ * throw a no_asynchronous_operation_exception.
+ */
+ template<typename Signature>
+ class SynchronousOperationRepositoryPartFused
+ : public interface::OperationRepositoryPart
+ {
+ typedef typename boost::function_traits<Signature>::result_type result_type;
+ //! The factory for converting data sources to C++ types in call()
+ typedef create_sequence<typename boost::function_types::parameter_types + //! The factory for converting data sources to C++ types in collect(). This includes SendHandle.
+ typedef create_sequence<typename boost::function_types::parameter_types + Operation<Signature>* op;
+ public:
+ SynchronousOperationRepositoryPartFused( Operation<Signature>* o)
+ : op(o)
+ {
+ }
+
+ virtual base::DataSourceBase::shared_ptr produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller) const
+ { throw interface::no_asynchronous_operation_exception("cannot use produceSend on synchronous operations"); }
+ virtual base::DataSourceBase::shared_ptr produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, internal::DataSource<bool>::shared_ptr blocking) const
+ { throw interface::no_asynchronous_operation_exception("cannot use produceCollect on synchronous operations"); }
+ virtual Handle produceSignal( base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args) const
+ { throw interface::no_asynchronous_operation_exception("cannot use produceSignal on synchronous operations"); }
+ virtual base::DataSourceBase::shared_ptr produceHandle() const
+ { throw interface::no_asynchronous_operation_exception("cannot use produceHandle on synchronous operations"); }
+
+ virtual std::string description() const {
+ return OperationRepositoryPartHelper::description( op );
+ }
+
+ virtual std::vector<interface::ArgumentDescription> getArgumentList() const {
+ std::vector<std::string> types;
+ for (unsigned int i = 1; i <= SynchronousOperationRepositoryPartFused::arity(); ++i )
+ types.push_back( SequenceFactory::GetType(i) );
+ return OperationRepositoryPartHelper::getArgumentList( op, SynchronousOperationRepositoryPartFused::arity(), types );
+ }
+
+ std::string resultType() const
+ {
+ return DataSourceTypeInfo<result_type>::getType() + DataSourceTypeInfo<result_type>::getQualifier();
+ }
+
+ unsigned int arity() const { return boost::function_traits<Signature>::arity; }
+
+ const types::TypeInfo* getArgumentType(unsigned int arg) const
+ {
+ if (arg == 0 )
+ return internal::DataSourceTypeInfo<result_type>::getTypeInfo();
+ return SequenceFactory::GetTypeInfo(arg);
+ }
+
+ unsigned int collectArity() const { return boost::function_traits< typename CollectType<Signature>::type >::arity; }
+
+ const types::TypeInfo* getCollectType(unsigned int arg) const
+ {
+ return CollectSequenceFactory::GetTypeInfo(arg);
+ }
+
+ base::DataSourceBase::shared_ptr produce(
+ const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller) const
+ {
+ // convert our args and signature into a boost::fusion Sequence.
+ if ( args.size() != SynchronousOperationRepositoryPartFused::arity() )
+ throw interface::wrong_number_of_args_exception(SynchronousOperationRepositoryPartFused::arity(), args.size() );
+ return new FusedMCallDataSource<Signature>(typename base::MethodBase<Signature>::shared_ptr(op->getMethod()->cloneI(caller)), SequenceFactory::sources(args.begin()) );
+ }
+
+ boost::shared_ptr<base::DisposableInterface> getLocalOperation() const {
+ return op->getImplementation();
+ }
+ };
+
/**
* OperationRepositoryPart implementation that uses boost::fusion
* to produce items. The methods invoked get their object pointer
diff --git a/rtt/scripting/ExpressionParser.cpp b/rtt/scripting/ExpressionParser.cpp
index 84d6646..203c88e 100644
--- a/rtt/scripting/ExpressionParser.cpp
+++ b/rtt/scripting/ExpressionParser.cpp
@@ -193,7 +193,7 @@ namespace RTT
peerparser.reset();

try {
- if ( meth == "collect" || meth == "collectIfDone") {
+ if ( (meth == "collect" || meth == "collectIfDone") && !ops->hasMember(mmethod) ) {
if ( ops->hasAttribute(obj) ) {
SendHandleAlias* sha = dynamic_cast<SendHandleAlias*>( peer->getValue(obj) );
if (sha) {
@@ -226,6 +226,10 @@ namespace RTT
throw parse_exception_wrong_type_of_argument
(obj, meth, e.whicharg, e.expected_, e.received_ );
}
+ catch( const std::exception& e)
+ {
+ throw parse_exception_fatal_semantic_error("While calling "+obj+"."+meth+": "+e.what());
+ }
}
assert( ret.get() );
}
diff --git a/rtt/transports/corba/OperationRepositoryI.cpp b/rtt/transports/corba/OperationRepositoryI.cpp
index d482991..52c5777 100644
--- a/rtt/transports/corba/OperationRepositoryI.cpp
+++ b/rtt/transports/corba/OperationRepositoryI.cpp
@@ -174,8 +174,14 @@ RTT_corba_COperationRepository_i::~RTT_corba_COperationRepository_i (void)

vector<string> flist = mfact->getNames();
rlist->length( flist.size() );
+ size_t drops=0;
for (size_t i=0; i != flist.size(); ++i)
- rlist[i] = CORBA::string_dup( flist[i].c_str() );
+ if ( !mfact->isSynchronous(flist[i]) ) {
+ rlist[i - drops] = CORBA::string_dup( flist[i].c_str() );
+ } else {
+ ++drops;
+ }
+ rlist->length( flist.size() - drops); // we don't show the synchronous operations.
return rlist._retn();
}

@@ -183,7 +189,7 @@ RTT_corba_COperationRepository_i::~RTT_corba_COperationRepository_i (void)
const char * operation)
{
CDescriptions_var ret = new CDescriptions();
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)))
throw ::RTT::corba::CNoSuchNameException( operation );
// operation found, convert args:
OperationRepository::Descriptions args = mfact->getArgumentList( string(operation) );
@@ -199,7 +205,7 @@ RTT_corba_COperationRepository_i::~RTT_corba_COperationRepository_i (void)
char * RTT_corba_COperationRepository_i::getResultType (
const char * operation)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() );
}
@@ -208,7 +214,7 @@ char* RTT_corba_COperationRepository_i::getArgumentType(
const char* operation,
CORBA::UShort nbr)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
if ( nbr > mfact->getPart(operation)->arity() )
throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() );
@@ -219,7 +225,7 @@ char* RTT_corba_COperationRepository_i::getCollectType(
const char* operation,
CORBA::UShort nbr)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
if ( nbr > mfact->getPart(operation)->collectArity() )
throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() );
@@ -230,7 +236,7 @@ char* RTT_corba_COperationRepository_i::getCollectType(
::CORBA::UShort RTT_corba_COperationRepository_i::getArity (
const char * operation)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
return mfact->getPart(operation)->arity();
}
@@ -238,7 +244,7 @@ char* RTT_corba_COperationRepository_i::getCollectType(
::CORBA::UShort RTT_corba_COperationRepository_i::getCollectArity (
const char * operation)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
return mfact->getPart(operation)->collectArity();
}
@@ -246,7 +252,7 @@ char* RTT_corba_COperationRepository_i::getCollectType(
char * RTT_corba_COperationRepository_i::getDescription (
const char * operation)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() );
}
@@ -255,6 +261,8 @@ void RTT_corba_COperationRepository_i::checkOperation (
const char * operation,
const ::RTT::corba::CAnyArguments & args)
{
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
+ throw ::RTT::corba::CNoSuchNameException( operation );
try {
OperationRepositoryPart* mofp = mfact->getPart(operation);
MethodC mc(mofp, operation, 0);
@@ -267,6 +275,8 @@ void RTT_corba_COperationRepository_i::checkOperation (
mc.arg(ds);
}
mc.check();
+ } catch (no_asynchronous_operation_exception& nao) {
+ throw ::RTT::corba::CNoSuchNameException(operation);
} catch (name_not_found_exception& nnf) {
throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
} catch (wrong_number_of_args_exception& wna) {
@@ -280,7 +290,7 @@ void RTT_corba_COperationRepository_i::checkOperation (
const char * operation,
::RTT::corba::CAnyArguments & args)
{
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
// convert Corba args to C++ args.
try {
@@ -315,6 +325,8 @@ void RTT_corba_COperationRepository_i::checkOperation (
} else {
orig.check(); // will throw
}
+ } catch (no_asynchronous_operation_exception& nao) {
+ throw ::RTT::corba::CNoSuchNameException( operation );
} catch ( name_not_found_exception& nnf ) {
throw ::RTT::corba::CNoSuchNameException( operation );
} catch ( wrong_number_of_args_exception& wna ) {
@@ -330,7 +342,7 @@ void RTT_corba_COperationRepository_i::checkOperation (
const ::RTT::corba::CAnyArguments & args)
{
// This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part.
- if ( mfact->hasMember( string( operation ) ) == false )
+ if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
throw ::RTT::corba::CNoSuchNameException( operation );
// convert Corba args to C++ args.
try {
@@ -348,6 +360,8 @@ void RTT_corba_COperationRepository_i::checkOperation (
} else {
orig.check(); // will throw
}
+ } catch (no_asynchronous_operation_exception& nao) {
+ throw ::RTT::corba::CNoSuchNameException( operation );
} catch ( name_not_found_exception& nnf ) {
throw ::RTT::corba::CNoSuchNameException( operation );
} catch ( wrong_number_of_args_exception& wna ) {