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