summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/Ice/Connection.cpp20
-rw-r--r--cpp/src/Ice/Incoming.cpp50
-rw-r--r--cpp/src/Ice/IncomingAsync.cpp16
-rw-r--r--cpp/test/Ice/exceptions/Test.ice2
-rw-r--r--cpp/test/Ice/exceptions/TestAMD.ice2
-rw-r--r--cpp/test/Ice/exceptions/TestAMDI.cpp14
-rw-r--r--cpp/test/Ice/exceptions/TestAMDI.h4
-rw-r--r--cpp/test/Ice/exceptions/TestI.cpp12
-rw-r--r--cpp/test/Ice/exceptions/TestI.h2
9 files changed, 111 insertions, 11 deletions
diff --git a/cpp/src/Ice/Connection.cpp b/cpp/src/Ice/Connection.cpp
index 4630e41787c..bb187af20fb 100644
--- a/cpp/src/Ice/Connection.cpp
+++ b/cpp/src/Ice/Connection.cpp
@@ -1303,7 +1303,7 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
//
try
{
- while(invoke-- > 0)
+ while(invoke > 0)
{
//
// Prepare the invocation.
@@ -1319,7 +1319,7 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
//
if(response)
{
- assert(invoke == 0); // No further invocations if a response is expected.
+ assert(invoke == 1); // No further invocations if a response is expected.
os->writeBlob(_replyHdr);
//
@@ -1333,7 +1333,7 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
//
// If there are more invocations, we need the stream back.
//
- if(invoke > 0)
+ if(--invoke > 0)
{
stream.swap(*is);
}
@@ -1343,6 +1343,20 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
{
IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
setState(StateClosed, ex);
+
+ //
+ // If invoke() above raised an exception, and therefore
+ // neither sendResponse() nor sendNoResponse() has been
+ // called, then we must decrement _dispatchCount here.
+ //
+ assert(invoke > 0);
+ assert(_dispatchCount > 0);
+ _dispatchCount -= invoke;
+ assert(_dispatchCount >= 0);
+ if(_dispatchCount == 0)
+ {
+ notifyAll();
+ }
}
}
diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp
index c4d1aabe532..acba0edf3b0 100644
--- a/cpp/src/Ice/Incoming.cpp
+++ b/cpp/src/Ice/Incoming.cpp
@@ -200,6 +200,8 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
}
catch(RequestFailedException& ex)
{
+ _is.endReadEncaps();
+
if(ex.id.name.empty())
{
ex.id = _current.id;
@@ -260,12 +262,17 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(ex.operation);
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
catch(const LocalException& ex)
{
+ _is.endReadEncaps();
+
if(_os.instance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
__warning(ex);
@@ -281,12 +288,17 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(str.str());
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
catch(const UserException& ex)
{
+ _is.endReadEncaps();
+
if(_os.instance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
__warning(ex);
@@ -302,12 +314,17 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(str.str());
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
catch(const Exception& ex)
{
+ _is.endReadEncaps();
+
if(_os.instance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
__warning(ex);
@@ -323,12 +340,17 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(str.str());
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
catch(const std::exception& ex)
{
+ _is.endReadEncaps();
+
if(_os.instance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
__warning(string("std::exception: ") + ex.what());
@@ -344,12 +366,17 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(str.str());
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
catch(...)
{
+ _is.endReadEncaps();
+
if(_os.instance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
__warning("unknown c++ exception");
@@ -364,8 +391,11 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
_os.write(reason);
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
return;
}
@@ -375,6 +405,8 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
// the caller of this operation.
//
+ _is.endReadEncaps();
+
//
// DispatchAsync is "pseudo dispatch status", used internally only
// to indicate async dispatch.
@@ -386,7 +418,6 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
// do *not* call __finishInvoke(), because the call is not
// finished yet.
//
- _is.endReadEncaps();
return;
}
@@ -427,6 +458,9 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager)
}
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
- _is.endReadEncaps();
}
diff --git a/cpp/src/Ice/IncomingAsync.cpp b/cpp/src/Ice/IncomingAsync.cpp
index deb7e81fd6b..5288047d08c 100644
--- a/cpp/src/Ice/IncomingAsync.cpp
+++ b/cpp/src/Ice/IncomingAsync.cpp
@@ -59,6 +59,10 @@ IceInternal::IncomingAsync::__response(bool ok)
}
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
}
@@ -186,6 +190,10 @@ IceInternal::IncomingAsync::__exception(const Exception& exc)
}
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
}
@@ -210,6 +218,10 @@ IceInternal::IncomingAsync::__exception(const std::exception& ex)
_os.write(str.str());
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
}
@@ -233,6 +245,10 @@ IceInternal::IncomingAsync::__exception()
_os.write(reason);
}
+ //
+ // Must be called last, so that if an exception is raised,
+ // this function is definitely *not* called.
+ //
__finishInvoke();
}
diff --git a/cpp/test/Ice/exceptions/Test.ice b/cpp/test/Ice/exceptions/Test.ice
index f78cdf8eebe..e2b7a0e5cf9 100644
--- a/cpp/test/Ice/exceptions/Test.ice
+++ b/cpp/test/Ice/exceptions/Test.ice
@@ -54,6 +54,7 @@ module Mod
{
void shutdown();
bool supportsUndeclaredExceptions();
+ bool supportsAssertException();
void throwAasA(int a) throws A;
void throwAorDasAorD(int a) throws A, D;
@@ -70,6 +71,7 @@ module Mod
void throwUndeclaredC(int a, int b, int c);
void throwLocalException();
void throwNonIceException();
+ void throwAssertException();
};
["ami"] interface WrongOperation
diff --git a/cpp/test/Ice/exceptions/TestAMD.ice b/cpp/test/Ice/exceptions/TestAMD.ice
index 1d5d55d8736..b528aba6642 100644
--- a/cpp/test/Ice/exceptions/TestAMD.ice
+++ b/cpp/test/Ice/exceptions/TestAMD.ice
@@ -50,6 +50,7 @@ module Mod
{
void shutdown();
bool supportsUndeclaredExceptions();
+ bool supportsAssertException();
void throwAasA(int a) throws A;
void throwAorDasAorD(int a) throws A, D;
@@ -66,6 +67,7 @@ module Mod
void throwUndeclaredC(int a, int b, int c);
void throwLocalException();
void throwNonIceException();
+ void throwAssertException();
};
["ami", "amd"] interface WrongOperation
diff --git a/cpp/test/Ice/exceptions/TestAMDI.cpp b/cpp/test/Ice/exceptions/TestAMDI.cpp
index 81e2cc8e04a..b0db069f61f 100644
--- a/cpp/test/Ice/exceptions/TestAMDI.cpp
+++ b/cpp/test/Ice/exceptions/TestAMDI.cpp
@@ -36,6 +36,13 @@ ThrowerI::supportsUndeclaredExceptions_async(const AMD_Thrower_supportsUndeclare
}
void
+ThrowerI::supportsAssertException_async(const AMD_Thrower_supportsAssertExceptionPtr& cb,
+ const Ice::Current&)
+{
+ cb->ice_response(false);
+}
+
+void
ThrowerI::throwAasA_async(const AMD_Thrower_throwAasAPtr& cb,
Ice::Int a, const Ice::Current&)
{
@@ -172,3 +179,10 @@ ThrowerI::throwNonIceException_async(const AMD_Thrower_throwNonIceExceptionPtr&,
{
throw int(12345);
}
+
+void
+ThrowerI::throwAssertException_async(const AMD_Thrower_throwAssertExceptionPtr&,
+ const Ice::Current&)
+{
+ assert(false); // Not supported in C++.
+}
diff --git a/cpp/test/Ice/exceptions/TestAMDI.h b/cpp/test/Ice/exceptions/TestAMDI.h
index eef4845a810..ce3bd9eee17 100644
--- a/cpp/test/Ice/exceptions/TestAMDI.h
+++ b/cpp/test/Ice/exceptions/TestAMDI.h
@@ -27,6 +27,8 @@ public:
const Ice::Current&);
virtual void supportsUndeclaredExceptions_async(const AMD_Thrower_supportsUndeclaredExceptionsPtr&,
const Ice::Current&);
+ virtual void supportsAssertException_async(const AMD_Thrower_supportsAssertExceptionPtr&,
+ const Ice::Current&);
virtual void throwAasA_async(const AMD_Thrower_throwAasAPtr&,
Ice::Int, const Ice::Current&);
@@ -56,6 +58,8 @@ public:
const Ice::Current&);
virtual void throwNonIceException_async(const AMD_Thrower_throwNonIceExceptionPtr&,
const Ice::Current&);
+ virtual void throwAssertException_async(const AMD_Thrower_throwAssertExceptionPtr&,
+ const Ice::Current&);
private:
diff --git a/cpp/test/Ice/exceptions/TestI.cpp b/cpp/test/Ice/exceptions/TestI.cpp
index cd2007e7a70..e31f141104e 100644
--- a/cpp/test/Ice/exceptions/TestI.cpp
+++ b/cpp/test/Ice/exceptions/TestI.cpp
@@ -32,6 +32,12 @@ ThrowerI::supportsUndeclaredExceptions(const Ice::Current&)
return true;
}
+bool
+ThrowerI::supportsAssertException(const Ice::Current&)
+{
+ return false;
+}
+
void
ThrowerI::throwAasA(Ice::Int a, const Ice::Current&)
{
@@ -141,3 +147,9 @@ ThrowerI::throwNonIceException(const Ice::Current&)
{
throw int(12345);
}
+
+void
+ThrowerI::throwAssertException(const Ice::Current&)
+{
+ assert(false); // Not supported in C++.
+}
diff --git a/cpp/test/Ice/exceptions/TestI.h b/cpp/test/Ice/exceptions/TestI.h
index dc113cb773b..6345ba7e799 100644
--- a/cpp/test/Ice/exceptions/TestI.h
+++ b/cpp/test/Ice/exceptions/TestI.h
@@ -25,6 +25,7 @@ public:
virtual void shutdown(const Ice::Current&);
virtual bool supportsUndeclaredExceptions(const Ice::Current&);
+ virtual bool supportsAssertException(const Ice::Current&);
virtual void throwAasA(Ice::Int, const Ice::Current&);
virtual void throwAorDasAorD(Ice::Int, const Ice::Current&);
@@ -41,6 +42,7 @@ public:
virtual void throwUndeclaredC(Ice::Int, Ice::Int, Ice::Int, const Ice::Current&);
virtual void throwLocalException(const Ice::Current&);
virtual void throwNonIceException(const Ice::Current&);
+ virtual void throwAssertException(const Ice::Current&);
private: