diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 11 | ||||
-rw-r--r-- | cpp/test/Ice/operations/TwowaysAMI.cpp | 43 |
2 files changed, 52 insertions, 2 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 813f04fa9e4..8ac6d2f6ba1 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -1649,8 +1649,6 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << ("const " + classScopedAMI + '_' + name + "Ptr& __cb") << paramsDeclAMI << "const ::Ice::Context& __ctx" << epar; C << sb; - // Async requests may only be sent twoway. - C << nl << "__checkTwowayOnly(\"" << name << "\");"; C << nl << "__cb->__invoke" << spar << "this" << argsAMI << "__ctx" << epar << ';'; C << eb; } @@ -4179,6 +4177,15 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) C << sb; C << nl << "static const ::std::string __operation(\"" << name << "\");"; C << nl << "__prepare(__prx, " << flatName << ", " << operationModeToString(p->mode()) << ", __ctx);"; + if(p->returnsData()) + { + C << nl << "if(!__prx->ice_isTwoway())"; + C << sb; + C << nl << "::Ice::TwowayOnlyException ex(__FILE__, __LINE__);"; + C << nl << "ex.operation = __operation;"; + C << nl << "throw ex;"; + C << eb; + } writeMarshalCode(C, inParams, 0); if(p->sendsClasses()) { diff --git a/cpp/test/Ice/operations/TwowaysAMI.cpp b/cpp/test/Ice/operations/TwowaysAMI.cpp index 0961a421cd3..de7599c7223 100644 --- a/cpp/test/Ice/operations/TwowaysAMI.cpp +++ b/cpp/test/Ice/operations/TwowaysAMI.cpp @@ -102,6 +102,25 @@ public: typedef IceUtil::Handle<AMI_MyClass_opByteI> AMI_MyClass_opByteIPtr; +class AMI_MyClass_opByteExI : public Test::AMI_MyClass_opByte, public CallbackBase +{ +public: + + virtual void ice_response(::Ice::Byte r, ::Ice::Byte b) + { + test(false); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + test(dynamic_cast<const ::Ice::Exception*>(&ex)); + called(); + } +}; + +typedef IceUtil::Handle<AMI_MyClass_opByteExI> AMI_MyClass_opByteExIPtr; + + class AMI_MyClass_opBoolI : public Test::AMI_MyClass_opBool, public CallbackBase { public: @@ -803,6 +822,30 @@ void twowaysAMI(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& p) { { + // Check that we can invoke a void operation via a oneway proxy. + Test::MyClassPrx oneway = Test::MyClassPrx::uncheckedCast(p->ice_oneway()); + AMI_MyClass_opVoidIPtr cb = new AMI_MyClass_opVoidI; + oneway->opVoid_async(cb); + test(cb->check()); + } + + { + // Check that a call to a twoway operation raises TwowayOnlyException + // in the ice_exception() callback instead of at the point of call. + Test::MyClassPrx oneway = Test::MyClassPrx::uncheckedCast(p->ice_oneway()); + AMI_MyClass_opByteExIPtr cb = new AMI_MyClass_opByteExI; + try + { + oneway->opByte_async(cb, 0, 0); + } + catch(const Ice::Exception&) + { + test(false); + } + test(cb->check()); + } + + { AMI_MyClass_opVoidIPtr cb = new AMI_MyClass_opVoidI; p->opVoid_async(cb); test(cb->check()); |