diff options
author | Benoit Foucher <benoit@zeroc.com> | 2018-11-13 15:28:58 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2018-11-13 17:35:34 +0100 |
commit | 45759a2b43d056d624e45a197ec10e1973c5a064 (patch) | |
tree | 7cadca70cbd702528e721eb778bf7429ff039c9a /cpp/src | |
parent | Do not compare char to EOF (diff) | |
download | ice-45759a2b43d056d624e45a197ec10e1973c5a064.tar.bz2 ice-45759a2b43d056d624e45a197ec10e1973c5a064.tar.xz ice-45759a2b43d056d624e45a197ec10e1973c5a064.zip |
Better fix for #291
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/ConnectionFactory.cpp | 90 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectionFactory.h | 3 |
2 files changed, 69 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(); } diff --git a/cpp/src/Ice/ConnectionFactory.h b/cpp/src/Ice/ConnectionFactory.h index f5f95ce9d4d..d44874d0b23 100644 --- a/cpp/src/Ice/ConnectionFactory.h +++ b/cpp/src/Ice/ConnectionFactory.h @@ -205,6 +205,9 @@ public: virtual void message(ThreadPoolCurrent&); virtual void finished(ThreadPoolCurrent&, bool); +#if TARGET_OS_IPHONE != 0 + void finish(); +#endif virtual std::string toString() const; virtual NativeInfoPtr getNativeInfo(); |