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 */
44 inline Socket_fdset::Socket_fdset() {
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__
Socket_IP
Base functionality for a INET domain Socket This call should be the starting point for all other unix...
Definition: socket_ip.h:27
Socket_IP::GetSocket
SOCKET GetSocket()
Gets the base socket type.
Definition: socket_ip.h:237
Socket_fdset
Definition: socket_fdset.h:16
Socket_fdset::WaitForWrite
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
Socket_fdset::WaitForError
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
Socket_fdset::clear
void clear()
Marks the content as empty.
Definition: socket_fdset.h:124
Socket_fdset::Socket_fdset
Socket_fdset()
The constructor.
Definition: socket_fdset.h:44
Socket_fdset::IsSetFor
bool IsSetFor(const Socket_IP &incon) const
check to see if a socket object has been marked for reading
Definition: socket_fdset.h:81
Time_Span
Definition: time_span.h:7
numeric_types.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pandabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Socket_Selector
Definition: socket_selector.h:7