Panda3D
|
00001 #ifndef __SOCKET_FDSET_H__ 00002 #define __SOCKET_FDSET_H__ 00003 00004 //////////////////////////////////////////////////// 00005 // 00006 //rhh 00007 // This class needs to be broken into 2 classes: the gathering class and the processing functions. 00008 // The functions should be set up as template functions 00009 // 00010 // Add a helper class socket_select. May want to totally separate the select and collect functionality 00011 // fits more with the normal Berkeley mind set... ** Not ** Should think about using POLL() on BSD-based systems 00012 // 00013 ////////////////////////////////////////////////////////// 00014 #include "pandabase.h" 00015 #include "numeric_types.h" 00016 #include "time_base.h" 00017 #include "socket_ip.h" 00018 00019 class Socket_fdset 00020 { 00021 PUBLISHED: 00022 00023 inline Socket_fdset(); 00024 inline void setForSocket(const Socket_IP &incon); 00025 inline bool IsSetFor(const Socket_IP & incon) const; 00026 inline int WaitForRead(bool zeroFds, PN_uint32 sleep_time = 0xffffffff); 00027 inline int WaitForWrite(bool zeroFds, PN_uint32 sleep_time = 0xffffffff); 00028 inline int WaitForError(bool zeroFds, PN_uint32 sleep_time = 0xffffffff); 00029 00030 00031 inline int WaitForRead(bool zeroFds, const Time_Span & timeout); 00032 inline void clear(); 00033 private: 00034 inline void setForSocketNative(const SOCKET inid); 00035 inline bool isSetForNative(const SOCKET inid) const; 00036 00037 friend struct Socket_Selector; 00038 SOCKET _maxid; 00039 mutable fd_set _the_set; 00040 }; 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function name : Socket_fdset::Socket_fdset 00044 // Description : The constructor 00045 //////////////////////////////////////////////////////////////////// 00046 inline Socket_fdset::Socket_fdset() 00047 { 00048 clear(); 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function name : Socket_fdset::setForSocketNative 00053 // Description : This does the physical manipulation of the set getting read for the base call 00054 //////////////////////////////////////////////////////////////////// 00055 inline void Socket_fdset::setForSocketNative(SOCKET inid) 00056 { 00057 assert( inid >= 0); 00058 #ifndef WIN32 00059 assert(inid < FD_SETSIZE); 00060 #endif 00061 00062 FD_SET(inid, &_the_set); 00063 if (_maxid < inid) 00064 _maxid = inid; 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function name : Socket_fdset::isSetForNative 00069 // Description : Answer the question: was the socket marked for reading 00070 // there's a subtle difference in the NSPR version: it will respond if 00071 // the socket had an error 00072 //////////////////////////////////////////////////////////////////// 00073 inline bool Socket_fdset::isSetForNative(SOCKET inid) const 00074 { 00075 assert( inid >= 0); 00076 #ifndef WIN32 00077 assert(inid < FD_SETSIZE); 00078 #endif 00079 00080 return (FD_ISSET(inid, &_the_set) != 0); 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function name : Socket_fdset::IsSetFor 00085 // Description : check to see if a socket object has been marked for reading 00086 //////////////////////////////////////////////////////////////////// 00087 inline bool Socket_fdset::IsSetFor(const Socket_IP & incon) const 00088 { 00089 return isSetForNative(incon.GetSocket()); 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function name : WaitForRead 00094 // Description : 00095 //////////////////////////////////////////////////////////////////// 00096 inline int Socket_fdset::WaitForRead(bool zeroFds, PN_uint32 sleep_time) 00097 { 00098 int retVal = 0; 00099 if (sleep_time == 0xffffffff) 00100 { 00101 retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, NULL); 00102 } 00103 else 00104 { 00105 timeval timeoutValue; 00106 timeoutValue.tv_sec = sleep_time / 1000; 00107 timeoutValue.tv_usec = (sleep_time % 1000) * 1000; 00108 00109 retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &timeoutValue); 00110 } 00111 if (zeroFds) 00112 clear(); 00113 00114 return retVal; 00115 } 00116 00117 ////////////////////////////////////////////////////////////// 00118 // Function name : Socket_fdset::WaitForRead 00119 // Description : 00120 ////////////////////////////////////////////////////////////// 00121 inline int Socket_fdset::WaitForRead(bool zeroFds, const Time_Span & timeout) 00122 { 00123 timeval localtv = timeout.GetTval(); 00124 00125 int retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &localtv); 00126 if (zeroFds) 00127 clear(); 00128 00129 return retVal; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function name : Socket_fdset::zeroOut 00134 // Description : Marks the content as empty 00135 //////////////////////////////////////////////////////////////////// 00136 inline void Socket_fdset::clear() 00137 { 00138 _maxid = 0; 00139 FD_ZERO(&_the_set); 00140 } 00141 00142 //////////////////////////////////////////////////////////////////// 00143 // Function name : Socket_fdset::setForSocket 00144 // Description : 00145 //////////////////////////////////////////////////////////////////// 00146 inline void Socket_fdset::setForSocket(const Socket_IP &incon) 00147 { 00148 setForSocketNative(incon.GetSocket()); 00149 } 00150 00151 //////////////////////////////// 00152 //////////////////////////////////////////////////////////////////// 00153 // Function name : Socket_fdset::WaitForWrite 00154 // Description : This is the function that will wait till 00155 // one of the sockets is ready for writing 00156 //////////////////////////////////////////////////////////////////// 00157 inline int Socket_fdset::WaitForWrite(bool zeroFds, PN_uint32 sleep_time) 00158 { 00159 int retVal = 0; 00160 if (sleep_time == 0xffffffff) 00161 { 00162 retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, NULL); 00163 } 00164 else 00165 { 00166 timeval timeoutValue; 00167 timeoutValue.tv_sec = sleep_time / 1000; 00168 timeoutValue.tv_usec = (sleep_time % 1000) * 1000; 00169 00170 retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, &timeoutValue); 00171 } 00172 if (zeroFds) 00173 clear(); 00174 00175 return retVal; 00176 } 00177 00178 ////////////////////////////////////////////////////////////// 00179 // Function name : Socket_fdset::WaitForError 00180 // Description : This is the function that will wait till 00181 // one of the sockets is in error state 00182 ////////////////////////////////////////////////////////////// 00183 inline int Socket_fdset::WaitForError(bool zeroFds, PN_uint32 sleep_time) 00184 { 00185 int retVal = 0; 00186 if (sleep_time == 0xffffffff) 00187 { 00188 retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, NULL); 00189 } 00190 else 00191 { 00192 timeval timeoutValue; 00193 timeoutValue.tv_sec = sleep_time / 1000; 00194 timeoutValue.tv_usec = (sleep_time % 1000) * 1000; 00195 00196 retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, &timeoutValue); 00197 } 00198 if (zeroFds) 00199 clear(); 00200 00201 return retVal; 00202 } 00203 00204 00205 #endif //__SOCKET_FDSET_H__