summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/CHANGES2
-rw-r--r--cpp/src/Ice/Connection.cpp60
-rw-r--r--cpp/src/Ice/Connection.h5
-rw-r--r--java/CHANGES2
-rw-r--r--java/src/IceInternal/Connection.java46
5 files changed, 57 insertions, 58 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 07d0162ed73..e8788ed673e 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,6 +1,8 @@
Changes since version 1.1.1
---------------------------
+- Fixed a crash that could happen during shutdown.
+
- Fixed a deadlock that could happen during connection establishment.
- Fixed deadlock during shutdown that can happen if a thread pool with
diff --git a/cpp/src/Ice/Connection.cpp b/cpp/src/Ice/Connection.cpp
index 74554edddb8..cfb84752654 100644
--- a/cpp/src/Ice/Connection.cpp
+++ b/cpp/src/Ice/Connection.cpp
@@ -236,7 +236,6 @@ IceInternal::Connection::isValidated() const
{
// See _queryMutex comment in header file.
IceUtil::Mutex::Lock sync(_queryMutex);
-
return _state > StateNotValidated;
}
@@ -245,7 +244,6 @@ IceInternal::Connection::isDestroyed() const
{
// See _queryMutex comment in header file.
IceUtil::Mutex::Lock sync(_queryMutex);
-
return _state >= StateClosing;
}
@@ -254,13 +252,7 @@ IceInternal::Connection::isFinished() const
{
// See _queryMutex comment in header file.
IceUtil::Mutex::Lock sync(_queryMutex);
-
- //
- // If _transceiver is 0, then _dispatchCount must also be 0;
- //
- assert(!(_transceiver == 0 && _dispatchCount != 0));
-
- return _transceiver == 0;
+ return _transceiver == 0 && _dispatchCount == 0;
}
void
@@ -771,17 +763,22 @@ IceInternal::Connection::sendResponse(BasicStream* os, Byte compressFlag)
try
{
- if(_state == StateClosed)
{
- assert(_dispatchCount == 0);
- return;
+ // See _queryMutex comment in header file.
+ IceUtil::Mutex::Lock sync(_queryMutex);
+ --_dispatchCount;
}
-
- if(--_dispatchCount == 0)
+
+ if(_dispatchCount == 0)
{
notifyAll();
}
+ if(_state == StateClosed)
+ {
+ return;
+ }
+
bool compress;
if(os->b.size() < 100) // Don't compress if message size is smaller than 100 bytes.
{
@@ -857,17 +854,22 @@ IceInternal::Connection::sendNoResponse()
try
{
- if(_state == StateClosed)
{
- assert(_dispatchCount == 0);
- return;
+ // See _queryMutex comment in header file.
+ IceUtil::Mutex::Lock sync(_queryMutex);
+ --_dispatchCount;
}
-
- if(--_dispatchCount == 0)
+
+ if(_dispatchCount == 0)
{
notifyAll();
}
+ if(_state == StateClosed)
+ {
+ return;
+ }
+
if(_state == StateClosing && _dispatchCount == 0)
{
initiateShutdown();
@@ -1059,7 +1061,11 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
traceRequest("received request", stream, _logger, _traceLevels);
stream.read(requestId);
invoke = 1;
- ++_dispatchCount;
+ {
+ // See _queryMutex comment in header file.
+ IceUtil::Mutex::Lock sync(_queryMutex);
+ ++_dispatchCount;
+ }
}
break;
}
@@ -1080,7 +1086,11 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
{
throw NegativeSizeException(__FILE__, __LINE__);
}
- _dispatchCount += invoke;
+ {
+ // See _queryMutex comment in header file.
+ IceUtil::Mutex::Lock sync(_queryMutex);
+ _dispatchCount += invoke;
+ }
}
break;
}
@@ -1406,6 +1416,8 @@ IceInternal::Connection::Connection(const InstancePtr& instance,
IceInternal::Connection::~Connection()
{
+ // See _queryMutex comment in header file.
+ IceUtil::Mutex::Lock sync(_queryMutex);
assert(_state == StateClosed);
assert(!_transceiver);
assert(_dispatchCount == 0);
@@ -1527,12 +1539,6 @@ IceInternal::Connection::setState(State state)
case StateClosed:
{
//
- // If we do a hard close, all outstanding requests are
- // disregarded.
- //
- _dispatchCount = 0;
-
- //
// If we change from not validated, we can close right
// away. Otherwise we first must make sure that we are
// registered, then we unregister, and let finished() do
diff --git a/cpp/src/Ice/Connection.h b/cpp/src/Ice/Connection.h
index 2198fafbb83..3868ad2d9ad 100644
--- a/cpp/src/Ice/Connection.h
+++ b/cpp/src/Ice/Connection.h
@@ -166,8 +166,9 @@ private:
BasicStream _batchStream;
int _batchRequestNum;
- int _dispatchCount; // The number of requests currently being dispatched.
- int _proxyCount; // The number of proxies using this connection.
+ int _dispatchCount;
+
+ int _proxyCount;
State _state;
diff --git a/java/CHANGES b/java/CHANGES
index 841d2ed4fe1..cbf7bcd4bdc 100644
--- a/java/CHANGES
+++ b/java/CHANGES
@@ -1,6 +1,8 @@
Changes since version 1.1.1
---------------------------
+- Fixed a crash that could happen during shutdown.
+
- Fixed a deadlock that could happen during connection establishment.
- Fixed deadlock during shutdown that can happen if a thread pool with
diff --git a/java/src/IceInternal/Connection.java b/java/src/IceInternal/Connection.java
index 6a11df5e324..0f0ed06b546 100644
--- a/java/src/IceInternal/Connection.java
+++ b/java/src/IceInternal/Connection.java
@@ -237,17 +237,12 @@ public final class Connection extends EventHandler
isFinished()
{
//
- // No synchronization necessary, _transceiver is declared
- // volatile. Synchronization is not possible here anyway,
- // because this function must not block.
- //
-
+ // No synchronization necessary, _transceiver and
+ // _dispatchCount are declared volatile. Synchronization is
+ // not possible here anyway, because this function must not
+ // block.
//
- // If _transceiver is null, then _dispatchCount must also be 0;
- //
- assert(!(_transceiver == null && _dispatchCount != 0));
-
- return _transceiver == null;
+ return _transceiver == null && _dispatchCount == 0;
}
public synchronized void
@@ -679,15 +674,14 @@ public final class Connection extends EventHandler
{
try
{
- if(_state == StateClosed)
+ if(--_dispatchCount == 0)
{
- assert(_dispatchCount == 0);
- return;
+ notifyAll();
}
- if(--_dispatchCount == 0)
+ if(_state == StateClosed)
{
- notifyAll();
+ return;
}
//
@@ -724,17 +718,16 @@ public final class Connection extends EventHandler
{
try
{
- if(_state == StateClosed)
- {
- assert(_dispatchCount == 0);
- return;
- }
-
if(--_dispatchCount == 0)
{
notifyAll();
}
+ if(_state == StateClosed)
+ {
+ return;
+ }
+
if(_state == StateClosing && _dispatchCount == 0)
{
initiateShutdown();
@@ -1312,12 +1305,6 @@ public final class Connection extends EventHandler
case StateClosed:
{
//
- // If we do a hard close, all outstanding requests are
- // disregarded.
- //
- _dispatchCount = 0;
-
- //
// If we change from not validated, we can close right
// away. Otherwise we first must make sure that we are
// registered, then we unregister, and let finished()
@@ -1530,8 +1517,9 @@ public final class Connection extends EventHandler
private boolean _batchStreamInUse;
private int _batchRequestNum;
- private int _dispatchCount; // The number of requests currently being dispatched.
- private int _proxyCount; // The number of proxies using this connection.
+ private volatile int _dispatchCount; // Must be volatile, see comment in isDestroyed().
+
+ private int _proxyCount;
private volatile int _state; // Must be volatile, see comment in isDestroyed().