summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES3
-rw-r--r--cpp/config/TestUtil.py4
-rw-r--r--cpp/include/Ice/Incoming.h16
-rw-r--r--cpp/include/Ice/IncomingAsync.h4
-rw-r--r--cpp/src/Ice/Incoming.cpp12
-rw-r--r--cpp/src/Ice/IncomingAsync.cpp13
-rw-r--r--cpp/src/slice2cpp/Gen.cpp18
-rw-r--r--cpp/src/slice2java/Gen.cpp10
8 files changed, 67 insertions, 13 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 319557d23a0..1771eaa47d1 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -17,3 +17,6 @@ Changes since version 1.0.0
- Renamed Lock and TryLock templates to LockT and TryLockT, to avoid
compilation problems with Sun Forte 6.2.
+
+- Fixed a bug with throwing exceptions in AMD calls after invoking
+ ice_response().
diff --git a/cpp/config/TestUtil.py b/cpp/config/TestUtil.py
index cf05fdf93d4..b0c8795427d 100644
--- a/cpp/config/TestUtil.py
+++ b/cpp/config/TestUtil.py
@@ -18,8 +18,8 @@
# protocol. Otherwise TCP is used.
#
-#protocol = ""
-protocol = "ssl"
+protocol = ""
+#protocol = "ssl"
#
# Set compressed to 1 in case you want to run the tests with
diff --git a/cpp/include/Ice/Incoming.h b/cpp/include/Ice/Incoming.h
index 31e465d9cb7..deb14e14d10 100644
--- a/cpp/include/Ice/Incoming.h
+++ b/cpp/include/Ice/Incoming.h
@@ -41,16 +41,22 @@ protected:
Ice::ServantLocatorPtr _locator;
Ice::LocalObjectPtr _cookie;
+ bool _response;
+
+ BasicStream _is;
+ BasicStream _os;
+
+//
+// Cannot be private. IncomingAsync needs _connection to initialize a
+// ConnectionPtr.
+//
+//private:
+
//
// Optimization. The connection may not be deleted while a
// stack-allocated Incoming still holds it.
//
Connection* _connection;
-
- bool _response;
-
- BasicStream _is;
- BasicStream _os;
};
class ICE_API Incoming : public IncomingBase
diff --git a/cpp/include/Ice/IncomingAsync.h b/cpp/include/Ice/IncomingAsync.h
index 8f8dd8c4d62..daadfe2acd9 100644
--- a/cpp/include/Ice/IncomingAsync.h
+++ b/cpp/include/Ice/IncomingAsync.h
@@ -42,6 +42,10 @@ protected:
BasicStream* __is() { return &_is; }
BasicStream* __os() { return &_os; }
+protected:
+
+ bool _finished;
+
private:
//
diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp
index 37f23a5a9a7..0088de43554 100644
--- a/cpp/src/Ice/Incoming.cpp
+++ b/cpp/src/Ice/Incoming.cpp
@@ -33,10 +33,10 @@ using namespace IceInternal;
IceInternal::IncomingBase::IncomingBase(Instance* instance, Connection* connection,
const ObjectAdapterPtr& adapter,
bool response) :
- _connection(connection),
_response(response),
_is(instance),
- _os(instance)
+ _os(instance),
+ _connection(connection)
{
_current.adapter = adapter;
}
@@ -46,10 +46,10 @@ IceInternal::IncomingBase::IncomingBase(IncomingBase& in) :
_servant(in._servant),
_locator(in._locator),
_cookie(in._cookie),
- _connection(in._connection),
_response(in._response),
_is(in._is.instance()),
- _os(in._os.instance())
+ _os(in._os.instance()),
+ _connection(in._connection)
{
_is.swap(in._is);
_os.swap(in._os);
@@ -62,7 +62,7 @@ IceInternal::IncomingBase::__finishInvoke(bool success)
{
_locator->finished(_current, _servant, _cookie);
}
-
+
if(success)
{
_is.endReadEncaps();
@@ -71,7 +71,7 @@ IceInternal::IncomingBase::__finishInvoke(bool success)
{
_is.skipReadEncaps();
}
-
+
//
// Send a response if necessary. If we don't need to send a
// response, we still need to tell the connection that we're
diff --git a/cpp/src/Ice/IncomingAsync.cpp b/cpp/src/Ice/IncomingAsync.cpp
index b9d34f7aa1e..fe3b6efb4a0 100644
--- a/cpp/src/Ice/IncomingAsync.cpp
+++ b/cpp/src/Ice/IncomingAsync.cpp
@@ -31,6 +31,7 @@ void IceInternal::decRef(AMD_Object_ice_invoke* p) { p->__decRef(); }
IceInternal::IncomingAsync::IncomingAsync(Incoming& in) :
IncomingBase(in),
+ _finished(false),
_instanceCopy(_is.instance()),
_connectionCopy(_connection)
{
@@ -39,6 +40,9 @@ IceInternal::IncomingAsync::IncomingAsync(Incoming& in) :
void
IceInternal::IncomingAsync::__response(bool ok)
{
+ assert(!_finished);
+ _finished = true;
+
if(_response)
{
_os.endWriteEncaps();
@@ -59,6 +63,9 @@ IceInternal::IncomingAsync::__response(bool ok)
void
IceInternal::IncomingAsync::__exception(const Exception& exc)
{
+ assert(!_finished);
+ _finished = true;
+
try
{
exc.ice_throw();
@@ -156,6 +163,9 @@ IceInternal::IncomingAsync::__exception(const Exception& exc)
void
IceInternal::IncomingAsync::__exception(const std::exception& ex)
{
+ assert(!_finished);
+ _finished = true;
+
if(_response)
{
_os.endWriteEncaps();
@@ -172,6 +182,9 @@ IceInternal::IncomingAsync::__exception(const std::exception& ex)
void
IceInternal::IncomingAsync::__exception()
{
+ assert(!_finished);
+ _finished = true;
+
if(_response)
{
_os.endWriteEncaps();
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index b68946529a9..1e9688b7f6f 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -3536,8 +3536,10 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
H.dec();
H << nl << "public:";
H.inc();
+
H << sp;
H << nl << classNameAMD << '_' << name << "(::IceInternal::Incoming&);";
+
H << sp;
H << nl << "virtual void ice_response(" << params << ");";
H << nl << "virtual void ice_exception(const ::Ice::Exception&);";
@@ -3552,9 +3554,12 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
C.dec();
C << sb;
C << eb;
+
C << sp << nl << "void" << nl << "::IceAsync" << classScopedAMD << '_' << name << "::ice_response("
<< paramsDecl << ')';
C << sb;
+ C << nl << "if(!_finished)";
+ C << sb;
if(ret || !outParams.empty())
{
C << nl << "try";
@@ -3570,9 +3575,13 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
}
C << nl << "__response(true);";
C << eb;
+ C << eb;
+
C << sp << nl << "void" << nl << "::IceAsync" << classScopedAMD << '_' << name
<< "::ice_exception(const ::Ice::Exception& ex)";
C << sb;
+ C << nl << "if(!_finished)";
+ C << sb;
if(throws.empty())
{
C << nl << "__exception(ex);";
@@ -3598,15 +3607,24 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
C << eb;
}
C << eb;
+ C << eb;
+
C << sp << nl << "void" << nl << "::IceAsync" << classScopedAMD << '_' << name
<< "::ice_exception(const ::std::exception& ex)";
C << sb;
+ C << nl << "if(!_finished)";
+ C << sb;
C << nl << "__exception(ex);";
C << eb;
+ C << eb;
+
C << sp << nl << "void" << nl << "::IceAsync" << classScopedAMD << '_' << name
<< "::ice_exception()";
C << sb;
+ C << nl << "if(!_finished)";
+ C << sb;
C << nl << "__exception();";
C << eb;
+ C << eb;
}
}
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index a52b714e9c7..b3e6c47cc60 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -3928,12 +3928,16 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
out << sp << nl << "final class " << classNameAMDI << '_' << name
<< " extends IceInternal.IncomingAsync implements " << classNameAMD << '_' << name;
out << sb;
+
out << sp << nl << "public" << nl << classNameAMDI << '_' << name << "(IceInternal.Incoming in)";
out << sb;
out << nl << "super(in);";
out << eb;
+
out << sp << nl << "public void" << nl << "ice_response(" << paramsAMD << ")";
out << sb;
+ out << nl << "if(!_finished)";
+ out << sb;
if(ret || !outParams.empty())
{
out << nl << "try";
@@ -3957,8 +3961,12 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
}
out << nl << "__response(true);";
out << eb;
+ out << eb;
+
out << sp << nl << "public void" << nl << "ice_exception(java.lang.Exception ex)";
out << sb;
+ out << nl << "if(!_finished)";
+ out << sb;
if(throws.empty())
{
out << nl << "__exception(ex);";
@@ -3985,6 +3993,8 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
out << eb;
}
out << eb;
+ out << eb;
+
out << eb << ';';
close();