Panda3D
socket_fdset.h
1 #ifndef __SOCKET_FDSET_H__
2 #define __SOCKET_FDSET_H__
3 
4 /*
5  * rhh This class needs to be broken into 2 classes: the gathering class and
6  * the processing functions. The functions should be set up as template
7  * functions Add a helper class socket_select. May want to totally separate
8  * the select and collect functionality fits more with the normal Berkeley
9  * mind set... ** Not ** Should think about using POLL() on BSD-based systems
10  */
11 #include "pandabase.h"
12 #include "numeric_types.h"
13 #include "time_base.h"
14 #include "socket_ip.h"
15 
16 class Socket_fdset {
17 PUBLISHED:
18  inline Socket_fdset();
19  inline void setForSocket(const Socket_IP &incon);
20  inline bool IsSetFor(const Socket_IP &incon) const;
21  inline int WaitForRead(bool zeroFds, uint32_t sleep_time = 0xffffffff);
22  inline int WaitForWrite(bool zeroFds, uint32_t sleep_time = 0xffffffff);
23  inline int WaitForError(bool zeroFds, uint32_t sleep_time = 0xffffffff);
24 
25  inline int WaitForRead(bool zeroFds, const Time_Span & timeout);
26  inline void clear();
27 
28 private:
29  inline void setForSocketNative(const SOCKET inid);
30  inline bool isSetForNative(const SOCKET inid) const;
31 
32  friend struct Socket_Selector;
33 
34  SOCKET _maxid;
35 
36 #ifndef CPPPARSER
37  mutable fd_set _the_set;
38 #endif
39 };
40 
41 /**
42  * The constructor
43  */
45  clear();
46 }
47 
48 /**
49  * This does the physical manipulation of the set getting read for the base
50  * call
51  */
52 inline void Socket_fdset::setForSocketNative(SOCKET inid)
53 {
54  assert( inid >= 0);
55 #ifndef WIN32
56  assert(inid < FD_SETSIZE);
57 #endif
58 
59  FD_SET(inid, &_the_set);
60  if (_maxid < inid)
61  _maxid = inid;
62 }
63 
64 /**
65  * Answer the question: was the socket marked for reading? there's a subtle
66  * difference in the NSPR version: it will respond if the socket had an error
67  */
68 inline bool Socket_fdset::isSetForNative(SOCKET inid) const
69 {
70  assert( inid >= 0);
71 #ifndef WIN32
72  assert(inid < FD_SETSIZE);
73 #endif
74 
75  return (FD_ISSET(inid, &_the_set) != 0);
76 }
77 
78 /**
79  * check to see if a socket object has been marked for reading
80  */
81 inline bool Socket_fdset::IsSetFor(const Socket_IP & incon) const
82 {
83  return isSetForNative(incon.GetSocket());
84 }
85 
86 /**
87  *
88  */
89 inline int Socket_fdset::WaitForRead(bool zeroFds, uint32_t sleep_time)
90 {
91  int retVal = 0;
92  if (sleep_time == 0xffffffff) {
93  retVal = DO_SELECT(_maxid + 1, &_the_set, nullptr, nullptr, nullptr);
94  } else {
95  timeval timeoutValue;
96  timeoutValue.tv_sec = sleep_time / 1000;
97  timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
98 
99  retVal = DO_SELECT(_maxid + 1, &_the_set, nullptr, nullptr, &timeoutValue);
100  }
101  if (zeroFds)
102  clear();
103 
104  return retVal;
105 }
106 
107 /**
108  *
109  */
110 inline int Socket_fdset::WaitForRead(bool zeroFds, const Time_Span & timeout)
111 {
112  timeval localtv = timeout.GetTval();
113 
114  int retVal = DO_SELECT(_maxid + 1, &_the_set, nullptr, nullptr, &localtv);
115  if (zeroFds)
116  clear();
117 
118  return retVal;
119 }
120 
121 /**
122  * Marks the content as empty
123  */
124 inline void Socket_fdset::clear()
125 {
126  _maxid = 0;
127  FD_ZERO(&_the_set);
128 }
129 
130 /**
131  *
132  */
133 inline void Socket_fdset::setForSocket(const Socket_IP &incon)
134 {
135  setForSocketNative(incon.GetSocket());
136 }
137 
138 /**
139  * This is the function that will wait till one of the sockets is ready for
140  * writing
141  */
142 inline int Socket_fdset::WaitForWrite(bool zeroFds, uint32_t sleep_time)
143 {
144  int retVal = 0;
145  if (sleep_time == 0xffffffff)
146  {
147  retVal = DO_SELECT(_maxid + 1, nullptr, &_the_set, nullptr, nullptr);
148  }
149  else
150  {
151  timeval timeoutValue;
152  timeoutValue.tv_sec = sleep_time / 1000;
153  timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
154 
155  retVal = DO_SELECT(_maxid + 1, nullptr, &_the_set, nullptr, &timeoutValue);
156  }
157  if (zeroFds)
158  clear();
159 
160  return retVal;
161 }
162 
163 /**
164  * This is the function that will wait till one of the sockets is in error
165  * state
166  */
167 inline int Socket_fdset::WaitForError(bool zeroFds, uint32_t sleep_time)
168 {
169  int retVal = 0;
170  if (sleep_time == 0xffffffff)
171  {
172  retVal = DO_SELECT(_maxid + 1, nullptr, nullptr, &_the_set, nullptr);
173  }
174  else
175  {
176  timeval timeoutValue;
177  timeoutValue.tv_sec = sleep_time / 1000;
178  timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
179 
180  retVal = DO_SELECT(_maxid + 1, nullptr, nullptr, &_the_set, &timeoutValue);
181  }
182  if (zeroFds)
183  clear();
184 
185  return retVal;
186 }
187 
188 
189 #endif //__SOCKET_FDSET_H__
int WaitForWrite(bool zeroFds, uint32_t sleep_time=0xffffffff)
This is the function that will wait till one of the sockets is ready for writing.
Definition: socket_fdset.h:142
int WaitForError(bool zeroFds, uint32_t sleep_time=0xffffffff)
This is the function that will wait till one of the sockets is in error state.
Definition: socket_fdset.h:167
Base functionality for a INET domain Socket This call should be the starting point for all other unix...
Definition: socket_ip.h:27
Socket_fdset()
The constructor.
Definition: socket_fdset.h:44
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool IsSetFor(const Socket_IP &incon) const
check to see if a socket object has been marked for reading
Definition: socket_fdset.h:81
void clear()
Marks the content as empty.
Definition: socket_fdset.h:124
SOCKET GetSocket()
Gets the base socket type.
Definition: socket_ip.h:237