Panda3D

socket_fdset.h

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__
 All Classes Functions Variables Enumerations