summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2017-03-03 09:47:30 -0800
committerMark Spruiell <mes@zeroc.com>2017-03-03 09:47:30 -0800
commit90cedfbbfbd69a5d7fae47bf3bd9662cf16ec08a (patch)
tree841a80bfae75e763ee502bbee0a1e69b6369f8cd /cpp/src
parentFix for ICE-7622 - no longer check for java-compat class names with the new m... (diff)
downloadice-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.cpp182
-rw-r--r--cpp/src/Ice/Selector.h1
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;