XmlRpc::XmlRpcDispatch Class Reference

#include <XmlRpcDispatch.h>

List of all members.


Detailed Description

An object which monitors file descriptors for events and performs callbacks when interesting events happen.


Public Types

enum  EventType { ReadableEvent = 1, WritableEvent = 2, Exception = 4 }
 Values indicating the type of events a source is interested in. More...

Public Member Functions

 XmlRpcDispatch ()
 Constructor.
 ~XmlRpcDispatch ()
void addSource (XmlRpcSource *source, unsigned eventMask)
 Monitor this source for the event types specified by the event mask and call its event handler when any of the events occur.
void removeSource (XmlRpcSource *source)
 Stop monitoring this source.
void setSourceEvents (XmlRpcSource *source, unsigned eventMask)
 Modify the types of events to watch for on this source.
void work (double msTime)
 Watch current set of sources and process events for the specified duration (in ms, -1 implies wait forever, or until exit is called).
void exit ()
 Exit from work routine.
void clear ()
 Clear all sources from the monitored sources list. Sources are closed.

Protected Types

typedef std::list< MonitoredSourceSourceList

Protected Member Functions

bool waitForAndProcessEvents (double timeout)
 Wait for I/O on any source, timeout, or interrupt signal.
double getTime ()

Protected Attributes

SourceList _sources
double _endTime
bool _doClear
bool _inWork

Classes

struct  MonitoredSource


Member Typedef Documentation

typedef std::list< MonitoredSource > XmlRpc::XmlRpcDispatch::SourceList [protected]


Member Enumeration Documentation

enum XmlRpc::XmlRpcDispatch::EventType

Values indicating the type of events a source is interested in.

Enumerator:
ReadableEvent  data available to read
WritableEvent  connected/data can be written without blocking
Exception  uh oh
00029                    {
00030       ReadableEvent = 1,    
00031       WritableEvent = 2,    
00032       Exception     = 4     
00033     };


Constructor & Destructor Documentation

XmlRpcDispatch::XmlRpcDispatch (  ) 

Constructor.

00027 {
00028   _endTime = -1.0;
00029   _doClear = false;
00030   _inWork = false;
00031 }

XmlRpcDispatch::~XmlRpcDispatch (  ) 

00035 {
00036 }


Member Function Documentation

void XmlRpcDispatch::addSource ( XmlRpcSource source,
unsigned  eventMask 
)

Monitor this source for the event types specified by the event mask and call its event handler when any of the events occur.

Parameters:
source The source to monitor
eventMask Which event types to watch for.
See also:
EventType
00042 {
00043   _sources.push_back(MonitoredSource(source, mask));
00044 }

void XmlRpcDispatch::removeSource ( XmlRpcSource source  ) 

Stop monitoring this source.

Parameters:
source The source to stop monitoring The source socket is not closed.
00049 {
00050   for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
00051     if (it->getSource() == source)
00052     {
00053       _sources.erase(it);
00054       break;
00055     }
00056 }

void XmlRpcDispatch::setSourceEvents ( XmlRpcSource source,
unsigned  eventMask 
)

Modify the types of events to watch for on this source.

00062 {
00063   for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
00064     if (it->getSource() == source)
00065     {
00066       it->getMask() = eventMask;
00067       break;
00068     }
00069 }

void XmlRpcDispatch::work ( double  msTime  ) 

Watch current set of sources and process events for the specified duration (in ms, -1 implies wait forever, or until exit is called).

00076 {
00077   // Compute end time
00078   double timeNow = getTime();
00079   _endTime = (timeout < 0.0) ? -1.0 : (timeNow + timeout);
00080   _doClear = false;
00081   _inWork = true;
00082 
00083   // Only work while there is something to monitor
00084   while (_sources.size() > 0) {
00085 
00086     // Wait for and dispatch events
00087     if ( ! waitForAndProcessEvents(timeout))
00088     {
00089       _inWork = false;
00090       return;
00091     }
00092 
00093 
00094     // Check whether to clear all sources
00095     if (_doClear)
00096     {
00097       SourceList closeList = _sources;
00098       _sources.clear();
00099       for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it) {
00100         XmlRpcSource *src = it->getSource();
00101         src->close();
00102       }
00103 
00104       _doClear = false;
00105     }
00106 
00107     // Check whether end time has passed or exit has been called
00108     if (_endTime == 0.0)        // Exit
00109       break;
00110     else if (_endTime > 0.0)    // Check for timeout
00111     {
00112       double t = getTime();
00113       if (t > _endTime)
00114         break;
00115 
00116       // Decrement timeout by elapsed time
00117       timeout -= (t - timeNow);
00118       if (timeout < 0.0) 
00119         timeout = 0.0;    // Shouldn't happen but its fp math...
00120       timeNow = t;
00121     }
00122   }
00123 
00124   _inWork = false;
00125 }

void XmlRpcDispatch::exit (  ) 

Exit from work routine.

00133 {
00134   _endTime = 0.0;   // Return from work asap
00135 }

void XmlRpcDispatch::clear (  ) 

Clear all sources from the monitored sources list. Sources are closed.

00141 {
00142   if (_inWork)
00143     _doClear = true;  // Finish reporting current events before clearing
00144   else
00145   {
00146     SourceList closeList = _sources;
00147     _sources.clear();
00148     for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it)
00149       it->getSource()->close();
00150   }
00151 }

bool XmlRpcDispatch::waitForAndProcessEvents ( double  timeout  )  [protected]

Wait for I/O on any source, timeout, or interrupt signal.

00177 {
00178 #if defined(_WINDOWS) && 0
00179 
00180   int nHandles = 0;
00181   SourceList::iterator it;
00182   for (it=_sources.begin(); it!=_sources.end(); ++it) {
00183     int fd = it->getSource()->getfd();
00184     int mask = 0;
00185     if (it->getMask() & ReadableEvent) mask = (FD_READ | FD_CLOSE | FD_ACCEPT);
00186     if (it->getMask() & WritableEvent) mask |= (FD_WRITE | FD_CLOSE);
00187 
00188 #else   // Posix
00189 
00190   // Construct the sets of descriptors we are interested in
00191   fd_set inFd, outFd, excFd;
00192   FD_ZERO(&inFd);
00193   FD_ZERO(&outFd);
00194   FD_ZERO(&excFd);
00195 
00196   int maxFd = -1;
00197   SourceList::iterator it;
00198   for (it=_sources.begin(); it!=_sources.end(); ++it) {
00199     int fd = it->getSource()->getfd();
00200     if (it->getMask() & ReadableEvent) FD_SET(fd, &inFd);
00201     if (it->getMask() & WritableEvent) FD_SET(fd, &outFd);
00202     if (it->getMask() & Exception)     FD_SET(fd, &excFd);
00203     if (it->getMask() && fd > maxFd)   maxFd = fd;
00204   }
00205 
00206   // Check for events
00207   int nEvents;
00208   if (_endTime < 0.0)
00209     nEvents = select(maxFd+1, &inFd, &outFd, &excFd, NULL);
00210   else 
00211   {
00212     struct timeval tv;
00213     tv.tv_sec = (int)floor(timeout);
00214     tv.tv_usec = ((int)floor(1000000.0 * (timeout-floor(timeout)))) % 1000000;
00215     nEvents = select(maxFd+1, &inFd, &outFd, &excFd, &tv);
00216   }
00217 
00218   if (nEvents < 0 && errno != EINTR)
00219   {
00220     XmlRpcUtil::error("Error in XmlRpcDispatch::work: error in select (%d).", nEvents);
00221     return false;
00222   }
00223 
00224   // Process events
00225   for (it=_sources.begin(); it != _sources.end(); )
00226   {
00227     SourceList::iterator thisIt = it++;
00228     XmlRpcSource* src = thisIt->getSource();
00229     int fd = src->getfd();
00230 
00231     if (fd <= maxFd) {
00232       // handleEvent is called once per event type signalled
00233       unsigned newMask = 0;
00234       int nset = 0;
00235       if (FD_ISSET(fd, &inFd))
00236       {
00237         newMask |= src->handleEvent(ReadableEvent);
00238         ++nset;
00239       }
00240       if (FD_ISSET(fd, &outFd))
00241       {
00242         newMask |= src->handleEvent(WritableEvent);
00243         ++nset;
00244       }
00245       if (FD_ISSET(fd, &excFd))
00246       {
00247         newMask |= src->handleEvent(Exception);
00248         ++nset;
00249       }
00250 
00251       // Some event occurred
00252       if (nset)
00253       {
00254         if (newMask)
00255           thisIt->getMask() = newMask;
00256         else       // Stop monitoring this one
00257         {
00258           _sources.erase(thisIt);
00259           if ( ! src->getKeepOpen())
00260             src->close();
00261         }
00262       }
00263     }
00264   }
00265 #endif
00266 
00267   return true;
00268 }

double XmlRpcDispatch::getTime (  )  [protected]

00157 {
00158 #ifdef USE_FTIME
00159   struct timeb  tbuff;
00160 
00161   ftime(&tbuff);
00162   return ((double) tbuff.time + ((double)tbuff.millitm / 1000.0) +
00163           ((double) tbuff.timezone * 60));
00164 #else
00165   struct timeval        tv;
00166   struct timezone       tz;
00167 
00168   gettimeofday(&tv, &tz);
00169   return (tv.tv_sec + tv.tv_usec / 1000000.0);
00170 #endif /* USE_FTIME */
00171 }


Member Data Documentation

SourceList XmlRpc::XmlRpcDispatch::_sources [protected]

double XmlRpc::XmlRpcDispatch::_endTime [protected]

bool XmlRpc::XmlRpcDispatch::_doClear [protected]

bool XmlRpc::XmlRpcDispatch::_inWork [protected]


The documentation for this class was generated from the following files:
Generated on Tue Jul 24 16:51:19 2007 for ITM OverSim by  doxygen 1.5.1