1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 #ifndef ICE_SELECTOR_H 6 #define ICE_SELECTOR_H 7 8 #include <IceUtil/StringUtil.h> 9 #include <IceUtil/Monitor.h> 10 #include <IceUtil/Mutex.h> 11 12 #include <Ice/Network.h> 13 #include <Ice/InstanceF.h> 14 #include <Ice/EventHandlerF.h> 15 #include <Ice/UniqueRef.h> 16 17 #if defined(ICE_USE_EPOLL) 18 # include <sys/epoll.h> 19 #elif defined(ICE_USE_KQUEUE) 20 # include <sys/event.h> 21 #elif defined(ICE_USE_IOCP) 22 // Nothing to include 23 #elif defined(ICE_USE_POLL) 24 # include <sys/poll.h> 25 #endif 26 27 #if defined(ICE_USE_CFSTREAM) 28 # include <IceUtil/RecMutex.h> 29 # include <IceUtil/Thread.h> 30 # include <set> 31 32 struct __CFRunLoop; 33 typedef struct __CFRunLoop * CFRunLoopRef; 34 35 struct __CFRunLoopSource; 36 typedef struct __CFRunLoopSource * CFRunLoopSourceRef; 37 38 struct __CFSocket; 39 typedef struct __CFSocket * CFSocketRef; 40 #endif 41 42 #if defined(ICE_OS_UWP) 43 # include <deque> 44 #endif 45 46 namespace IceInternal 47 { 48 49 // 50 // Exception raised if select times out. 51 // 52 class SelectorTimeoutException 53 { 54 }; 55 56 #if defined(ICE_USE_IOCP) || defined(ICE_OS_UWP) 57 58 class Selector 59 { 60 #if defined(ICE_OS_UWP) 61 struct SelectEvent 62 { SelectEventSelectEvent63 SelectEvent(const EventHandlerPtr& handler, SocketOperation status) : handler(handler), status(status) 64 { 65 } 66 67 EventHandlerPtr handler; 68 SocketOperation status; 69 }; 70 #endif 71 72 public: 73 74 Selector(const InstancePtr&); 75 ~Selector(); 76 77 #ifdef ICE_USE_IOCP 78 void setup(int); 79 #endif 80 void destroy(); 81 82 void initialize(EventHandler*); 83 void update(EventHandler*, SocketOperation, SocketOperation); 84 void finish(EventHandler*); 85 86 void ready(EventHandler*, SocketOperation, bool); 87 88 #ifdef ICE_USE_IOCP 89 EventHandler* getNextHandler(SocketOperation&, DWORD&, int&, int); 90 #else 91 EventHandler* getNextHandler(SocketOperation&, int); 92 #endif 93 94 void completed(EventHandler*, SocketOperation); 95 96 private: 97 98 const InstancePtr _instance; 99 #ifdef ICE_USE_IOCP 100 HANDLE _handle; 101 #else 102 IceUtil::Monitor<IceUtil::Mutex> _monitor; 103 std::deque<SelectEvent> _events; 104 #endif 105 }; 106 107 #elif defined(ICE_USE_KQUEUE) || defined(ICE_USE_EPOLL) || defined(ICE_USE_SELECT) || defined(ICE_USE_POLL) 108 109 class Selector 110 { 111 public: 112 113 Selector(const InstancePtr&); 114 ~Selector(); 115 116 void destroy(); 117 initialize(EventHandler *)118 void initialize(EventHandler*) 119 { 120 // Nothing to do 121 } 122 void update(EventHandler*, SocketOperation, SocketOperation); 123 void enable(EventHandler*, SocketOperation); 124 void disable(EventHandler*, SocketOperation); 125 bool finish(EventHandler*, bool); 126 127 void ready(EventHandler*, SocketOperation, bool); 128 129 void startSelect(); 130 void finishSelect(std::vector<std::pair<EventHandler*, SocketOperation> >&); 131 void select(int); 132 133 private: 134 135 void wakeup(); 136 void checkReady(EventHandler*); 137 void updateSelector(); 138 void updateSelectorForEventHandler(EventHandler*, SocketOperation, SocketOperation); 139 140 const InstancePtr _instance; 141 142 SOCKET _fdIntrRead; 143 SOCKET _fdIntrWrite; 144 bool _interrupted; 145 bool _selectNow; 146 int _count; 147 bool _selecting; 148 std::map<EventHandlerPtr, SocketOperation> _readyHandlers; 149 150 #if defined(ICE_USE_EPOLL) 151 std::vector<struct epoll_event> _events; 152 int _queueFd; 153 #elif defined(ICE_USE_KQUEUE) 154 std::vector<struct kevent> _events; 155 std::vector<struct kevent> _changes; 156 int _queueFd; 157 #elif defined(ICE_USE_SELECT) 158 std::vector<std::pair<EventHandler*, SocketOperation> > _changes; 159 std::map<SOCKET, EventHandler*> _handlers; 160 161 fd_set _readFdSet; 162 fd_set _writeFdSet; 163 fd_set _errorFdSet; 164 fd_set _selectedReadFdSet; 165 fd_set _selectedWriteFdSet; 166 fd_set _selectedErrorFdSet; 167 168 fd_set* fdSetCopy(fd_set & dest,fd_set & src)169 fdSetCopy(fd_set& dest, fd_set& src) 170 { 171 if(src.fd_count > 0) 172 { 173 dest.fd_count = src.fd_count; 174 memcpy(dest.fd_array, src.fd_array, sizeof(SOCKET) * src.fd_count); 175 return &dest; 176 } 177 return 0; 178 } 179 #elif defined(ICE_USE_POLL) 180 std::vector<std::pair<EventHandler*, SocketOperation> > _changes; 181 std::map<SOCKET, EventHandler*> _handlers; 182 std::vector<struct pollfd> _pollFdSet; 183 #endif 184 }; 185 186 #elif defined(ICE_USE_CFSTREAM) 187 188 class Selector; 189 190 class SelectorReadyCallback : public IceUtil::Shared 191 { 192 public: 193 ~SelectorReadyCallback()194 virtual ~SelectorReadyCallback() { } 195 virtual void readyCallback(SocketOperation, int = 0) = 0; 196 }; 197 198 class StreamNativeInfo : public NativeInfo 199 { 200 public: 201 StreamNativeInfo(SOCKET fd)202 StreamNativeInfo(SOCKET fd) : NativeInfo(fd), _connectError(0) 203 { 204 } 205 206 virtual void initStreams(SelectorReadyCallback*) = 0; 207 virtual SocketOperation registerWithRunLoop(SocketOperation) = 0; 208 virtual SocketOperation unregisterFromRunLoop(SocketOperation, bool) = 0; 209 virtual void closeStreams() = 0; 210 setConnectError(int error)211 void setConnectError(int error) 212 { 213 _connectError = error; 214 } 215 216 private: 217 218 int _connectError; 219 }; 220 typedef IceUtil::Handle<StreamNativeInfo> StreamNativeInfoPtr; 221 222 class EventHandlerWrapper : public SelectorReadyCallback 223 { 224 public: 225 226 EventHandlerWrapper(EventHandler*, Selector&); 227 ~EventHandlerWrapper(); 228 229 void updateRunLoop(); 230 231 virtual void readyCallback(SocketOperation, int = 0); 232 void ready(SocketOperation, int); 233 234 SocketOperation readyOp(); 235 bool checkReady(); 236 237 bool update(SocketOperation, SocketOperation); 238 bool finish(); 239 240 bool operator<(const EventHandlerWrapper& o) 241 { 242 return this < &o; 243 } 244 245 private: 246 247 friend class Selector; 248 249 EventHandlerPtr _handler; 250 StreamNativeInfoPtr _streamNativeInfo; 251 Selector& _selector; 252 SocketOperation _ready; 253 bool _finish; 254 IceInternal::UniqueRef<CFSocketRef> _socket; 255 IceInternal::UniqueRef<CFRunLoopSourceRef> _source; 256 }; 257 typedef IceUtil::Handle<EventHandlerWrapper> EventHandlerWrapperPtr; 258 259 class Selector : IceUtil::Monitor<IceUtil::RecMutex> 260 { 261 262 public: 263 264 Selector(const InstancePtr&); 265 virtual ~Selector(); 266 267 void destroy(); 268 269 void initialize(EventHandler*); 270 void update(EventHandler*, SocketOperation, SocketOperation); 271 void enable(EventHandler*, SocketOperation); 272 void disable(EventHandler*, SocketOperation); 273 bool finish(EventHandler*, bool); 274 275 void ready(EventHandler*, SocketOperation, bool); 276 277 void startSelect(); 278 void finishSelect(std::vector<std::pair<EventHandler*, SocketOperation> >&); 279 void select(int); 280 281 void processInterrupt(); 282 void run(); 283 284 private: 285 286 void ready(EventHandlerWrapper*, SocketOperation, int = 0); 287 void addReadyHandler(EventHandlerWrapper*); 288 289 friend class EventHandlerWrapper; 290 291 InstancePtr _instance; 292 IceUtil::ThreadPtr _thread; 293 CFRunLoopRef _runLoop; 294 IceInternal::UniqueRef<CFRunLoopSourceRef> _source; 295 bool _destroyed; 296 297 std::set<EventHandlerWrapperPtr> _changes; 298 299 std::set<EventHandlerWrapperPtr> _readyHandlers; 300 std::vector<std::pair<EventHandlerWrapperPtr, SocketOperation> > _selectedHandlers; 301 std::map<EventHandler*, EventHandlerWrapperPtr> _wrappers; 302 }; 303 304 #endif 305 306 } 307 308 #endif 309