diff options
Diffstat (limited to 'cpp/src/Ice/ConnectionI.cpp')
-rw-r--r-- | cpp/src/Ice/ConnectionI.cpp | 101 |
1 files changed, 63 insertions, 38 deletions
diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index 22b4c28cf23..bb3052b86e1 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -1572,6 +1572,7 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, size_t threadPerConnectionStackSize) : EventHandler(instance), _threadPerConnection(threadPerConnection), + _threadPerConnectionStackSize(threadPerConnectionStackSize), _transceiver(transceiver), _desc(transceiver->toString()), _type(transceiver->type()), @@ -1633,17 +1634,17 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, _servantManager = adapterImpl->getServantManager(); } - __setNoDelete(true); - try + if(!threadPerConnection) { - if(!threadPerConnection) + // + // Only set _threadPool if we really need it, i.e., if we are + // not in thread per connection mode. Thread pools have lazy + // initialization in Instance, and we don't want them to be + // created if they are not needed. + // + __setNoDelete(true); + try { - // - // Only set _threadPool if we really need it, i.e., if we are - // not in thread per connection mode. Thread pools have lazy - // initialization in Instance, and we don't want them to be - // created if they are not needed. - // if(adapterImpl) { const_cast<ThreadPoolPtr&>(_threadPool) = adapterImpl->getThreadPool(); @@ -1654,41 +1655,22 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, } _threadPool->incFdsInUse(); } - else + catch(const IceUtil::Exception& ex) { - // - // If we are in thread per connection mode, create the - // thread for this connection. - // - _thread = new ThreadPerConnection(this); - _thread->start(threadPerConnectionStackSize); - } - } - catch(const IceUtil::Exception& ex) - { - { - Error out(_logger); - if(threadPerConnection) + try { - out << "cannot create thread for connection:\n" << ex; + _transceiver->close(); } - // Otherwise with thread pool the thread pool itself - // prints a warning if the threads cannot be created. - } - - try - { - _transceiver->close(); - } - catch(const LocalException&) - { - // Here we ignore any exceptions in close(). + catch(const LocalException&) + { + // Here we ignore any exceptions in close(). + } + + __setNoDelete(false); + ex.ice_throw(); } - __setNoDelete(false); - ex.ice_throw(); } - __setNoDelete(false); } Ice::ConnectionI::~ConnectionI() @@ -1700,6 +1682,49 @@ Ice::ConnectionI::~ConnectionI() } void +Ice::ConnectionI::start() +{ + // + // If we are in thread per connection mode, create the thread for this connection. + // We can't start the thread in the constructor because it can cause a race condition + // (see bug 1718). + // + if(_threadPerConnection) + { + try + { + _thread = new ThreadPerConnection(this); + _thread->start(_threadPerConnectionStackSize); + } + catch(const IceUtil::Exception& ex) + { + { + Error out(_logger); + out << "cannot create thread for connection:\n" << ex; + } + + try + { + _transceiver->close(); + } + catch(const LocalException&) + { + // Here we ignore any exceptions in close(). + } + + // + // Clean up. + // + _transceiver = 0; + _thread = 0; + _state = StateClosed; + + ex.ice_throw(); + } + } +} + +void Ice::ConnectionI::setState(State state, const LocalException& ex) { // |