summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Connection.cpp
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2004-01-13 16:07:56 +0000
committerMarc Laukien <marc@zeroc.com>2004-01-13 16:07:56 +0000
commit7db65aa3d43b934793aa7cc03c5adbe1f1876a20 (patch)
treefac7ee47f9b4d85a70b99df9c5f00d879a366206 /cpp/src/Ice/Connection.cpp
parentminor cleanup (diff)
downloadice-7db65aa3d43b934793aa7cc03c5adbe1f1876a20.tar.bz2
ice-7db65aa3d43b934793aa7cc03c5adbe1f1876a20.tar.xz
ice-7db65aa3d43b934793aa7cc03c5adbe1f1876a20.zip
promotion fix
Diffstat (limited to 'cpp/src/Ice/Connection.cpp')
-rw-r--r--cpp/src/Ice/Connection.cpp71
1 files changed, 51 insertions, 20 deletions
diff --git a/cpp/src/Ice/Connection.cpp b/cpp/src/Ice/Connection.cpp
index 56c9f90245e..0bd263a26b6 100644
--- a/cpp/src/Ice/Connection.cpp
+++ b/cpp/src/Ice/Connection.cpp
@@ -996,19 +996,63 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
return;
}
- OutgoingAsyncPtr outAsync;
+ //
+ // We need a special handling for close connection messages. If we
+ // get a close connection message, we must *first* set the state
+ // to closed, and *then* promote a follower thread. Otherwise we get
+ // lots of bogus warnings about connections being lost.
+ //
+ if(messageType == closeConnectionMsg)
+ {
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ if(_state == StateClosed)
+ {
+ threadPool->promoteFollower();
+ return;
+ }
+ try
+ {
+ traceHeader("received close connection", stream, _logger, _traceLevels);
+ if(_endpoint->datagram())
+ {
+ if(_warn)
+ {
+ Warning out(_logger);
+ out << "ignoring close connection message for datagram connection:\n"
+ << _transceiver->toString();
+ }
+ }
+ else
+ {
+ setState(StateClosed, CloseConnectionException(__FILE__, __LINE__));
+ }
+ }
+ catch(const LocalException& ex)
+ {
+ setState(StateClosed, ex);
+ }
+
+ threadPool->promoteFollower();
+ return;
+ }
+
+ //
+ // For all other messages, we can promote a follower right away,
+ // without setting the state first, or holding the mutex lock.
+ //
+ threadPool->promoteFollower();
+
+ OutgoingAsyncPtr outAsync;
Int invoke = 0;
Int requestId = 0;
{
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
- threadPool->promoteFollower();
-
if(_state == StateClosed)
{
- IceUtil::ThreadControl::yield();
return;
}
@@ -1165,20 +1209,7 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
case closeConnectionMsg:
{
- traceHeader("received close connection", stream, _logger, _traceLevels);
- if(_endpoint->datagram())
- {
- if(_warn)
- {
- Warning out(_logger);
- out << "ignoring close connection message for datagram connection:\n"
- << _transceiver->toString();
- }
- }
- else
- {
- throw CloseConnectionException(__FILE__, __LINE__);
- }
+ assert(false); // Message has special handling above.
break;
}
@@ -1261,6 +1292,8 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
void
IceInternal::Connection::finished(const ThreadPoolPtr& threadPool)
{
+ threadPool->promoteFollower();
+
auto_ptr<LocalException> closeException;
map<Int, Outgoing*> requests;
@@ -1269,8 +1302,6 @@ IceInternal::Connection::finished(const ThreadPoolPtr& threadPool)
{
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
- threadPool->promoteFollower();
-
if(_state == StateActive || _state == StateClosing)
{
registerWithPool();