1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/private/selectdispatcher.h
3 // Purpose:     wxSelectDispatcher class
4 // Authors:     Lukasz Michalski and Vadim Zeitlin
5 // Created:     December 2006
6 // Copyright:   (c) Lukasz Michalski
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 #ifndef _WX_PRIVATE_SELECTDISPATCHER_H_
11 #define _WX_PRIVATE_SELECTDISPATCHER_H_
12 
13 #include "wx/defs.h"
14 
15 #if wxUSE_SELECT_DISPATCHER
16 
17 #if defined(HAVE_SYS_SELECT_H)
18     #include <sys/time.h>
19     #include <sys/select.h>
20 #endif
21 
22 #include <sys/types.h>
23 
24 #include "wx/thread.h"
25 #include "wx/private/fdiodispatcher.h"
26 
27 // helper class storing all the select() fd sets
28 class WXDLLIMPEXP_BASE wxSelectSets
29 {
30 public:
31     // ctor zeroes out all fd_sets
32     wxSelectSets();
33 
34     // default copy ctor, assignment operator and dtor are ok
35 
36 
37     // return true if fd appears in any of the sets
38     bool HasFD(int fd) const;
39 
40     // add or remove FD to our sets depending on whether flags contains
41     // wxFDIO_INPUT/OUTPUT/EXCEPTION bits
42     bool SetFD(int fd, int flags);
43 
44     // same as SetFD() except it unsets the bits set in the flags for the given
45     // fd
ClearFD(int fd)46     bool ClearFD(int fd)
47     {
48         return SetFD(fd, 0);
49     }
50 
51 
52     // call select() with our sets: the other parameters are the same as for
53     // select() itself
54     int Select(int nfds, struct timeval *tv);
55 
56     // call the handler methods corresponding to the sets having this fd if it
57     // is present in any set and return true if it is
58     bool Handle(int fd, wxFDIOHandler& handler) const;
59 
60 private:
61     typedef void (wxFDIOHandler::*Callback)();
62 
63     // the FD sets indices
64     enum
65     {
66         Read,
67         Write,
68         Except,
69         Max
70     };
71 
72     // the sets used with select()
73     fd_set m_fds[Max];
74 
75     // the wxFDIO_XXX flags, functions and names (used for debug messages only)
76     // corresponding to the FD sets above
77     static int ms_flags[Max];
78     static const char *ms_names[Max];
79     static Callback ms_handlers[Max];
80 };
81 
82 class WXDLLIMPEXP_BASE wxSelectDispatcher : public wxMappedFDIODispatcher
83 {
84 public:
85     // default ctor
wxSelectDispatcher()86     wxSelectDispatcher() { m_maxFD = -1; }
87 
88     // implement pure virtual methods of the base class
89     virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags = wxFDIO_ALL) wxOVERRIDE;
90     virtual bool ModifyFD(int fd, wxFDIOHandler *handler, int flags = wxFDIO_ALL) wxOVERRIDE;
91     virtual bool UnregisterFD(int fd) wxOVERRIDE;
92     virtual bool HasPending() const wxOVERRIDE;
93     virtual int Dispatch(int timeout = TIMEOUT_INFINITE) wxOVERRIDE;
94 
95 private:
96     // common part of RegisterFD() and ModifyFD()
97     bool DoUpdateFDAndHandler(int fd, wxFDIOHandler *handler, int flags);
98 
99     // call the handlers for the fds present in the given sets, return the
100     // number of handlers we called
101     int ProcessSets(const wxSelectSets& sets);
102 
103     // helper of ProcessSets(): call the handler if its fd is in the set
104     void DoProcessFD(int fd, const fd_set& fds, wxFDIOHandler *handler,
105                      const char *name);
106 
107     // common part of HasPending() and Dispatch(): calls select() with the
108     // specified timeout
109     int DoSelect(wxSelectSets& sets, int timeout) const;
110 
111 
112 #if wxUSE_THREADS
113     wxCriticalSection m_cs;
114 #endif // wxUSE_THREADS
115 
116     // the select sets containing all the registered fds
117     wxSelectSets m_sets;
118 
119     // the highest registered fd value or -1 if none
120     int m_maxFD;
121 };
122 
123 #endif // wxUSE_SELECT_DISPATCHER
124 
125 #endif // _WX_PRIVATE_SOCKETEVTDISPATCH_H_
126