summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES3
-rw-r--r--cpp/include/IceUtil/Cond.h4
-rw-r--r--cpp/src/Ice/Connection.cpp43
-rw-r--r--cpp/src/Ice/Connection.h3
4 files changed, 41 insertions, 12 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 9c213fc95ee..15362cae844 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,6 +1,9 @@
Changes since version 1.2.0
---------------------------
+- Fixed a problem with servers not shutting down properly under
+ certain circumstances.
+
- IceUtil::Thread now calls srand() in each new thread (Windows only).
- When unmarshaling a string sequence parameter, Ice was not clearing
diff --git a/cpp/include/IceUtil/Cond.h b/cpp/include/IceUtil/Cond.h
index 65ea4393ae9..c60f33552be 100644
--- a/cpp/include/IceUtil/Cond.h
+++ b/cpp/include/IceUtil/Cond.h
@@ -93,7 +93,7 @@ public:
template <typename Lock> inline void
wait(const Lock& lock) const
{
- if (!lock.acquired())
+ if(!lock.acquired())
{
throw ThreadLockedException(__FILE__, __LINE__);
}
@@ -110,7 +110,7 @@ public:
template <typename Lock> inline bool
timedWait(const Lock& lock, const Time& timeout) const
{
- if (!lock.acquired())
+ if(!lock.acquired())
{
throw ThreadLockedException(__FILE__, __LINE__);
}
diff --git a/cpp/src/Ice/Connection.cpp b/cpp/src/Ice/Connection.cpp
index 0bd263a26b6..d03b16e70e4 100644
--- a/cpp/src/Ice/Connection.cpp
+++ b/cpp/src/Ice/Connection.cpp
@@ -278,12 +278,13 @@ IceInternal::Connection::waitUntilFinished()
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
//
- // We wait indefinitely until all outstanding requests are
- // completed. Otherwise we couldn't guarantee that there are no
- // outstanding calls when deactivate() is called on the servant
- // locators.
+ // We wait indefinitely until connection closing has been
+ // initiated. We also wait indefinitely until all outstanding
+ // requests are completed. Otherwise we couldn't guarantee that
+ // there are no outstanding calls when deactivate() is called on
+ // the servant locators.
//
- while(_dispatchCount > 0)
+ while(_state < StateClosing || _dispatchCount > 0)
{
wait();
}
@@ -294,13 +295,35 @@ IceInternal::Connection::waitUntilFinished()
//
while(_transceiver)
{
- if(_endpoint->timeout() >= 0)
+ if(_state != StateClosed && _endpoint->timeout() >= 0)
{
- if(!timedWait(IceUtil::Time::milliSeconds(_endpoint->timeout())))
+ IceUtil::Time timeout = IceUtil::Time::milliSeconds(_endpoint->timeout());
+ IceUtil::Time waitTime = _stateTime + timeout - IceUtil::Time::now();
+
+ if(waitTime > IceUtil::Time())
{
+ //
+ // We must wait a bit longer until we close this
+ // connection.
+ //
+ if(!timedWait(IceUtil::Time::milliSeconds(waitTime)))
+ {
+ setState(StateClosed, CloseTimeoutException(__FILE__, __LINE__));
+ }
+ }
+ else
+ {
+ //
+ // We already waited long enough, so let's close this
+ // connection!
+ //
setState(StateClosed, CloseTimeoutException(__FILE__, __LINE__));
- // No return here, we must still wait until _transceiver becomes null.
}
+
+ //
+ // No return here, we must still wait until _transceiver
+ // becomes null.
+ //
}
else
{
@@ -1409,7 +1432,8 @@ IceInternal::Connection::Connection(const InstancePtr& instance,
_batchRequestNum(0),
_dispatchCount(0),
_proxyCount(0),
- _state(StateNotValidated)
+ _state(StateNotValidated),
+ _stateTime(IceUtil::Time::now())
{
if(_adapter)
{
@@ -1649,6 +1673,7 @@ IceInternal::Connection::setState(State state)
// See _queryMutex comment in header file.
IceUtil::Mutex::Lock sync(_queryMutex);
_state = state;
+ _stateTime = IceUtil::Time::now();
}
notifyAll();
diff --git a/cpp/src/Ice/Connection.h b/cpp/src/Ice/Connection.h
index 3868ad2d9ad..b5e8023d709 100644
--- a/cpp/src/Ice/Connection.h
+++ b/cpp/src/Ice/Connection.h
@@ -170,7 +170,8 @@ private:
int _proxyCount;
- State _state;
+ State _state; // The current state.
+ IceUtil::Time _stateTime; // The time when the state was changed the last time.
//
// We need a special mutex for the isDestroyed() and isFinished()