summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/ConnectionFactory.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2018-11-13 15:28:58 +0100
committerBenoit Foucher <benoit@zeroc.com>2018-11-13 17:35:34 +0100
commit45759a2b43d056d624e45a197ec10e1973c5a064 (patch)
tree7cadca70cbd702528e721eb778bf7429ff039c9a /cpp/src/Ice/ConnectionFactory.cpp
parentDo not compare char to EOF (diff)
downloadice-45759a2b43d056d624e45a197ec10e1973c5a064.tar.bz2
ice-45759a2b43d056d624e45a197ec10e1973c5a064.tar.xz
ice-45759a2b43d056d624e45a197ec10e1973c5a064.zip
Better fix for #291
Diffstat (limited to 'cpp/src/Ice/ConnectionFactory.cpp')
-rw-r--r--cpp/src/Ice/ConnectionFactory.cpp90
1 files changed, 66 insertions, 24 deletions
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp
index f6f61e6640a..41c7dd448c6 100644
--- a/cpp/src/Ice/ConnectionFactory.cpp
+++ b/cpp/src/Ice/ConnectionFactory.cpp
@@ -152,6 +152,27 @@ private:
InstancePtr _instance;
};
+#if TARGET_OS_IPHONE != 0
+class FinishCall : public DispatchWorkItem
+{
+public:
+
+ FinishCall(const IncomingConnectionFactoryPtr& factory) : _factory(factory)
+ {
+ }
+
+ virtual void
+ run()
+ {
+ _factory->finish();
+ }
+
+private:
+
+ const IncomingConnectionFactoryPtr _factory;
+};
+#endif
+
}
bool
@@ -1431,9 +1452,13 @@ IceInternal::IncomingConnectionFactory::finishAsync(SocketOperation)
Error out(_instance->initializationData().logger);
out << "couldn't accept connection:\n" << ex << '\n' << _acceptor->toString();
- if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
+ if(_acceptorStarted)
{
- closeAcceptor();
+ _acceptorStarted = false;
+ if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
+ {
+ closeAcceptor();
+ }
}
}
return _state < StateClosed;
@@ -1502,6 +1527,8 @@ IceInternal::IncomingConnectionFactory::message(ThreadPoolCurrent& current)
Error out(_instance->initializationData().logger);
out << "can't accept more connections:\n" << ex << '\n' << _acceptor->toString();
+ assert(_acceptorStarted);
+ _acceptorStarted = false;
if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
{
closeAcceptor();
@@ -1562,7 +1589,7 @@ IceInternal::IncomingConnectionFactory::finished(ThreadPoolCurrent&, bool close)
IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
if(_state < StateClosed)
{
- if(_acceptorStarted && close)
+ if(close)
{
closeAcceptor();
}
@@ -1578,22 +1605,29 @@ IceInternal::IncomingConnectionFactory::finished(ThreadPoolCurrent&, bool close)
}
return;
}
- else if(_state == StateClosed)
- {
- setState(StateFinished);
- if(_acceptorStarted && close)
- {
- closeAcceptor();
- }
+ assert(_state == StateClosed);
+ setState(StateFinished);
+
+ if(close)
+ {
+ closeAcceptor();
+ }
#if TARGET_OS_IPHONE != 0
- sync.release();
- unregisterForBackgroundNotification(ICE_SHARED_FROM_THIS);
+ sync.release();
+ finish();
#endif
- }
}
+#if TARGET_OS_IPHONE != 0
+void
+IceInternal::IncomingConnectionFactory::finish()
+{
+ unregisterForBackgroundNotification(ICE_SHARED_FROM_THIS);
+}
+#endif
+
string
IceInternal::IncomingConnectionFactory::toString() const
{
@@ -1703,7 +1737,7 @@ IceInternal::IncomingConnectionFactory::stopAcceptor()
}
_acceptorStopped = true;
-
+ _acceptorStarted = false;
if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
{
closeAcceptor();
@@ -1842,20 +1876,28 @@ IceInternal::IncomingConnectionFactory::setState(State state)
case StateClosed:
{
- //
- // If possible, close the acceptor now to prevent new connections from
- // being accepted while we are deactivating. This is especially useful
- // if there are no more threads in the thread pool available to dispatch
- // the finish() call. Not all selector implementations do support this
- // however.
- //
- if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
+ if(_acceptorStarted)
{
- if(_acceptorStarted)
+ //
+ // If possible, close the acceptor now to prevent new connections from
+ // being accepted while we are deactivating. This is especially useful
+ // if there are no more threads in the thread pool available to dispatch
+ // the finish() call. Not all selector implementations do support this
+ // however.
+ //
+ _acceptorStarted = false;
+ if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true))
{
closeAcceptor();
}
}
+ else
+ {
+#if TARGET_OS_IPHONE != 0
+ _adapter->getThreadPool()->dispatch(new FinishCall(ICE_SHARED_FROM_THIS));
+#endif
+ state = StateFinished;
+ }
#ifdef ICE_CPP11_COMPILER
for(const auto& conn : _connections)
@@ -1930,6 +1972,6 @@ IceInternal::IncomingConnectionFactory::closeAcceptor()
out << "stopping to accept " << _endpoint->protocol() << " connections at " << _acceptor->toString();
}
- _acceptorStarted = false;
+ assert(!_acceptorStarted);
_acceptor->close();
}