diff options
author | Mark Spruiell <mes@zeroc.com> | 2017-03-03 09:47:30 -0800 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2017-03-03 09:47:30 -0800 |
commit | 90cedfbbfbd69a5d7fae47bf3bd9662cf16ec08a (patch) | |
tree | 841a80bfae75e763ee502bbee0a1e69b6369f8cd /cpp/src | |
parent | Fix for ICE-7622 - no longer check for java-compat class names with the new m... (diff) | |
download | ice-90cedfbbfbd69a5d7fae47bf3bd9662cf16ec08a.tar.bz2 ice-90cedfbbfbd69a5d7fae47bf3bd9662cf16ec08a.tar.xz ice-90cedfbbfbd69a5d7fae47bf3bd9662cf16ec08a.zip |
C++ selector fix for BT+SSL
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/Selector.cpp | 182 | ||||
-rw-r--r-- | cpp/src/Ice/Selector.h | 1 |
2 files changed, 95 insertions, 88 deletions
diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp index d4bb49af4c4..ebffee5325e 100644 --- a/cpp/src/Ice/Selector.cpp +++ b/cpp/src/Ice/Selector.cpp @@ -351,96 +351,10 @@ Selector::update(EventHandler* handler, SocketOperation remove, SocketOperation checkReady(handler); NativeInfoPtr nativeInfo = handler->getNativeInfo(); - if(!nativeInfo || nativeInfo->fd() == INVALID_SOCKET) - { - if(!nativeInfo->newFd()) // If no new FD is set, nothing to do. - { - return; - } - - // If a new FD is set, we update the selector to add operations for the FD, there's - // nothing to remove from the selector because the FD wasn't previously set. - assert(!handler->_disabled); - previous = SocketOperationNone; - remove = SocketOperationNone; - if(!add) - { - return; - } - } - -#if defined(ICE_USE_EPOLL) - SOCKET fd = nativeInfo->fd(); - epoll_event event; - memset(&event, 0, sizeof(epoll_event)); - event.data.ptr = handler; - SocketOperation status = handler->_registered; - if(handler->_disabled) - { - status = static_cast<SocketOperation>(status & ~handler->_disabled); - previous = static_cast<SocketOperation>(previous & ~handler->_disabled); - } - event.events |= status & SocketOperationRead ? EPOLLIN : 0; - event.events |= status & SocketOperationWrite ? EPOLLOUT : 0; - int op; - if(!previous && status) - { - op = EPOLL_CTL_ADD; - } - else if(previous && !status) - { - op = EPOLL_CTL_DEL; - } - else if(previous == status) - { - return; - } - else + if(nativeInfo && nativeInfo->fd() != INVALID_SOCKET) { - op = EPOLL_CTL_MOD; + updateSelectorForEventHandler(handler, remove, add); } - if(epoll_ctl(_queueFd, op, fd, &event) != 0) - { - Ice::Error out(_instance->initializationData().logger); - out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); - } -#elif defined(ICE_USE_KQUEUE) - SOCKET fd = nativeInfo->fd(); - if(remove & SocketOperationRead) - { - struct kevent ev; - EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, handler); - _changes.push_back(ev); - } - if(remove & SocketOperationWrite) - { - struct kevent ev; - EV_SET(&ev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, handler); - _changes.push_back(ev); - } - if(add & SocketOperationRead) - { - struct kevent ev; - EV_SET(&ev, fd, EVFILT_READ, EV_ADD | (handler->_disabled & SocketOperationRead ? EV_DISABLE : 0), 0, 0, - handler); - _changes.push_back(ev); - } - if(add & SocketOperationWrite) - { - struct kevent ev; - EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD | (handler->_disabled & SocketOperationWrite ? EV_DISABLE : 0), 0, 0, - handler); - _changes.push_back(ev); - } - if(_selecting) - { - updateSelector(); - } -#else - _changes.push_back(make_pair(handler, static_cast<SocketOperation>(handler->_registered & ~handler->_disabled))); - wakeup(); -#endif - checkReady(handler); } void @@ -577,6 +491,16 @@ Selector::ready(EventHandler* handler, SocketOperation status, bool value) return; // Nothing to do if ready state already correctly set. } + if(status & SocketOperationConnect) + { + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(nativeInfo && nativeInfo->newFd() && handler->_registered) + { + // If new FD is set after connect, register the FD with the selector. + updateSelectorForEventHandler(handler, SocketOperationNone, handler->_registered); + } + } + if(value) { handler->_ready = static_cast<SocketOperation>(handler->_ready | status); @@ -983,6 +907,88 @@ Selector::updateSelector() #endif } +void +Selector::updateSelectorForEventHandler(EventHandler* handler, SocketOperation remove, SocketOperation add) +{ +#if defined(ICE_USE_EPOLL) + SocketOperation previous = handler->_registered; + previous = static_cast<SocketOperation>(previous & ~add); + previous = static_cast<SocketOperation>(previous | remove); + SOCKET fd = handler->getNativeInfo()->fd(); + assert(fd != INVALID_SOCKET); + epoll_event event; + memset(&event, 0, sizeof(epoll_event)); + event.data.ptr = handler; + SocketOperation status = handler->_registered; + if(handler->_disabled) + { + status = static_cast<SocketOperation>(status & ~handler->_disabled); + previous = static_cast<SocketOperation>(previous & ~handler->_disabled); + } + event.events |= status & SocketOperationRead ? EPOLLIN : 0; + event.events |= status & SocketOperationWrite ? EPOLLOUT : 0; + int op; + if(!previous && status) + { + op = EPOLL_CTL_ADD; + } + else if(previous && !status) + { + op = EPOLL_CTL_DEL; + } + else if(previous == status) + { + return; + } + else + { + op = EPOLL_CTL_MOD; + } + if(epoll_ctl(_queueFd, op, fd, &event) != 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_KQUEUE) + SOCKET fd = handler->getNativeInfo()->fd(); + assert(fd != INVALID_SOCKET); + if(remove & SocketOperationRead) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, handler); + _changes.push_back(ev); + } + if(remove & SocketOperationWrite) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, handler); + _changes.push_back(ev); + } + if(add & SocketOperationRead) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_READ, EV_ADD | (handler->_disabled & SocketOperationRead ? EV_DISABLE : 0), 0, 0, + handler); + _changes.push_back(ev); + } + if(add & SocketOperationWrite) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD | (handler->_disabled & SocketOperationWrite ? EV_DISABLE : 0), 0, 0, + handler); + _changes.push_back(ev); + } + if(_selecting) + { + updateSelector(); + } +#else + _changes.push_back(make_pair(handler, static_cast<SocketOperation>(handler->_registered & ~handler->_disabled))); + wakeup(); +#endif + checkReady(handler); +} + #elif defined(ICE_USE_CFSTREAM) namespace diff --git a/cpp/src/Ice/Selector.h b/cpp/src/Ice/Selector.h index 05ff0574e35..674151a6683 100644 --- a/cpp/src/Ice/Selector.h +++ b/cpp/src/Ice/Selector.h @@ -141,6 +141,7 @@ private: void wakeup(); void checkReady(EventHandler*); void updateSelector(); + void updateSelectorForEventHandler(EventHandler*, SocketOperation, SocketOperation); const InstancePtr _instance; |