Main Page | Class Hierarchy | Class List | File List | Class Members

misc.hh

00001 #ifndef MTASKER_MISC_HH
00002 #define MTASKER_MISC_HH
00003 
00004 #include <stdio.h>
00005 #include <errno.h>
00006 #include <asm/page.h> 
00007 #include <asm/poll.h> 
00008 #include <netinet/in.h>
00009 #include <string.h>
00010 #include <sys/socket.h>
00011 #include <sys/types.h>
00012 #include <stdlib.h>
00013 #include <unistd.h>
00014 
00015 
00017 class SocketMultiplex
00018 {
00019 public:
00020   typedef vector<Socket *>svect_t;
00021   virtual ~SocketMultiplex(){}
00022   virtual void addReaders(svect_t& readers)=0;
00023   virtual void addWriters(svect_t& readers)=0;
00024   virtual void addErrors(svect_t& readers)=0;
00025   virtual void addReader(Socket *s)=0;
00026   virtual void addWriter(Socket *s)=0;
00027   virtual void addError(Socket *s)=0;
00028   virtual void run(svect_t& readers, svect_t& writers, svect_t& errors)=0;
00029 };
00030 
00031 
00033 
00034 class SelectSocketMultiplex : public SocketMultiplex
00035 {
00036 public:
00038   void addReaders(svect_t& readers)
00039   {
00040     adds(readers, d_readers);
00041   }
00043   void addWriters(svect_t& readers)
00044   {
00045     adds(readers, d_writers);
00046   }
00048   void addErrors(svect_t& readers)
00049   {
00050     adds(readers, d_errors);
00051   }
00052 
00054   void addReader(Socket *s)
00055   {
00056     add(s, d_readers);
00057   }
00059   void addWriter(Socket *s)
00060   {
00061     add(s, d_writers);
00062   }
00064   void addError(Socket *s)
00065   {
00066     add(s, d_errors);
00067   }
00068 
00075   void run(svect_t& readers, svect_t& writers, svect_t& errors)
00076   {
00077     fd_set rfds, wfds, efds;
00078     FD_ZERO(&rfds);
00079     FD_ZERO(&wfds);
00080     FD_ZERO(&efds);
00081     
00082     int maxfd=0;
00083     for(svect_t::const_iterator i=d_readers.begin();i!=d_readers.end();++i) {
00084       maxfd=max((*i)->getHandle(),maxfd);
00085       FD_SET((*i)->getHandle(),&rfds);
00086     }
00087     for(svect_t::const_iterator i=d_writers.begin();i!=d_writers.end();++i) {
00088       maxfd=max((*i)->getHandle(),maxfd);
00089       FD_SET((*i)->getHandle(),&wfds);
00090     }
00091     for(svect_t::const_iterator i=d_errors.begin();i!=d_errors.end();++i) {
00092       maxfd=max((*i)->getHandle(),maxfd);
00093       FD_SET((*i)->getHandle(),&efds);
00094     }
00095 
00096     struct timeval tv;
00097     tv.tv_usec=0;
00098     tv.tv_sec=1;
00099     int res=select(maxfd+1,&rfds,&wfds,&efds,&tv);
00100     if(res<0)
00101       throw NetworkError("Select: "+string(strerror(errno)));
00102 
00103     readers.clear();
00104     writers.clear();
00105     errors.clear();
00106 
00107     if(res==0)
00108       return;
00109       
00110     for(svect_t::const_iterator i=d_readers.begin();i!=d_readers.end();++i) 
00111       if(FD_ISSET((*i)->getHandle(), &rfds))
00112         readers.push_back(*i);
00113     
00114     for(svect_t::const_iterator i=d_writers.begin();i!=d_writers.end();++i) 
00115       if(FD_ISSET((*i)->getHandle(), &wfds))
00116         writers.push_back(*i);
00117 
00118     for(svect_t::const_iterator i=d_errors.begin();i!=d_errors.end();++i) 
00119       if(FD_ISSET((*i)->getHandle(), &efds))
00120         errors.push_back(*i);
00121 
00122   }
00123 private:
00124 
00125   void adds(svect_t &toadd, svect_t &addto) {
00126     for(svect_t::const_iterator i=toadd.begin();i!=toadd.end();++i) 
00127       add(*i, addto);
00128   }
00129   void add(Socket *s, svect_t& addto)
00130   {
00131     addto.push_back(s);
00132   }
00133 
00134   svect_t d_readers, d_writers, d_errors;
00135 
00136 };
00137 
00138 
00139 template <typename Container>
00140 void
00141 stringtok (Container &container, string const &in,
00142            const char * const delimiters = " \t\n")
00143 {
00144   const string::size_type len = in.length();
00145   string::size_type i = 0;
00146   
00147   while (i<len) {
00148     // eat leading whitespace
00149     i = in.find_first_not_of (delimiters, i);
00150     if (i == string::npos)
00151       return;   // nothing left but white space
00152     
00153     // find the end of the token
00154     string::size_type j = in.find_first_of (delimiters, i);
00155     
00156     // push token
00157     if (j == string::npos) {
00158       container.push_back (in.substr(i));
00159       return;
00160     } else
00161       container.push_back (in.substr(i, j-i));
00162     
00163     // set up for next loop
00164     i = j + 1;
00165   }
00166 }
00167 
00168 #endif

Generated on Sun Feb 8 12:07:52 2004 for MTasker by doxygen 1.3.5