Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes

XmlRpc::XmlRpcDispatch Class Reference

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

#include <XmlRpcDispatch.h>

List of all members.

Classes

struct  MonitoredSource

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
< MonitoredSource
SourceList

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

Detailed Description

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

Definition at line 28 of file XmlRpcDispatch.h.


Member Typedef Documentation

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

Definition at line 85 of file XmlRpcDispatch.h.


Member Enumeration Documentation

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

Definition at line 35 of file XmlRpcDispatch.h.


Constructor & Destructor Documentation

XmlRpcDispatch::XmlRpcDispatch (  ) 

Constructor.

Definition at line 35 of file XmlRpcDispatch.cc.

{
  _endTime = -1.0;
  _doClear = false;
  _inWork = false;
}

XmlRpcDispatch::~XmlRpcDispatch (  ) 

Definition at line 43 of file XmlRpcDispatch.cc.

{
}


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

Definition at line 50 of file XmlRpcDispatch.cc.

Referenced by XmlRpc::XmlRpcServer::bindAndListen(), XmlRpc::XmlRpcServer::dispatchConnection(), and XmlRpc::XmlRpcClient::setupConnection().

{
  _sources.push_back(MonitoredSource(source, mask));
}

void XmlRpcDispatch::clear (  ) 

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

Definition at line 149 of file XmlRpcDispatch.cc.

Referenced by XmlRpc::XmlRpcServer::shutdown().

{
  if (_inWork)
    _doClear = true;  // Finish reporting current events before clearing
  else
  {
    SourceList closeList = _sources;
    _sources.clear();
    for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it)
      it->getSource()->close();
  }
}

void XmlRpcDispatch::exit (  ) 

Exit from work routine.

Definition at line 141 of file XmlRpcDispatch.cc.

Referenced by XmlRpc::XmlRpcClient::close(), and XmlRpc::XmlRpcServer::exit().

{
  _endTime = 0.0;   // Return from work asap
}

double XmlRpcDispatch::getTime (  )  [protected]

Definition at line 165 of file XmlRpcDispatch.cc.

Referenced by work().

{
#ifdef USE_FTIME
  struct timeb  tbuff;

  ftime(&tbuff);
  return ((double) tbuff.time + ((double)tbuff.millitm / 1000.0) +
          ((double) tbuff.timezone * 60));
#else
  struct timeval        tv;
  struct timezone       tz;

  gettimeofday(&tv, &tz);
  return (tv.tv_sec + tv.tv_usec / 1000000.0);
#endif /* USE_FTIME */
}

void XmlRpcDispatch::removeSource ( XmlRpcSource source  ) 

Stop monitoring this source.

Parameters:
source The source to stop monitoring The source socket is not closed.

Definition at line 57 of file XmlRpcDispatch.cc.

Referenced by XmlRpc::XmlRpcClient::close(), XmlRpc::XmlRpcServer::removeConnection(), and XmlRpc::XmlRpcClient::setupConnection().

{
  for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
    if (it->getSource() == source)
    {
      _sources.erase(it);
      break;
    }
}

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

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

Definition at line 70 of file XmlRpcDispatch.cc.

{
  for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
    if (it->getSource() == source)
    {
      it->getMask() = eventMask;
      break;
    }
}

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

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

Definition at line 185 of file XmlRpcDispatch.cc.

Referenced by work().

{
#if defined(_WINDOWS) && 0

  int nHandles = 0;
  SourceList::iterator it;
  for (it=_sources.begin(); it!=_sources.end(); ++it) {
    int fd = it->getSource()->getfd();
    int mask = 0;
    if (it->getMask() & ReadableEvent) mask = (FD_READ | PACKET_FD_CLOSE | FD_ACCEPT);
    if (it->getMask() & WritableEvent) mask |= (FD_WRITE | PACKET_FD_CLOSE);

#else   // Posix

  // Construct the sets of descriptors we are interested in
  fd_set inFd, outFd, excFd;
  FD_ZERO(&inFd);
  FD_ZERO(&outFd);
  FD_ZERO(&excFd);

  int maxFd = -1;
  SourceList::iterator it;
  for (it=_sources.begin(); it!=_sources.end(); ++it) {
    int fd = it->getSource()->getfd();
    if (it->getMask() & ReadableEvent) FD_SET(fd, &inFd);
    if (it->getMask() & WritableEvent) FD_SET(fd, &outFd);
    if (it->getMask() & Exception)     FD_SET(fd, &excFd);
    if (it->getMask() && fd > maxFd)   maxFd = fd;
  }

  // Check for events
  int nEvents;
  if (_endTime < 0.0)
    nEvents = select(maxFd+1, &inFd, &outFd, &excFd, NULL);
  else
  {
    struct timeval tv;
    tv.tv_sec = (int)floor(timeout);
    tv.tv_usec = ((int)floor(1000000.0 * (timeout-floor(timeout)))) % 1000000;
    nEvents = select(maxFd+1, &inFd, &outFd, &excFd, &tv);
  }

  if (nEvents < 0 && errno != EINTR)
  {
    XmlRpcUtil::error("Error in XmlRpcDispatch::work: error in select (%d).", nEvents);
    return false;
  }

  // Process events
  for (it=_sources.begin(); it != _sources.end(); )
  {
    SourceList::iterator thisIt = it++;
    XmlRpcSource* src = thisIt->getSource();
    int fd = src->getfd();

    if (fd <= maxFd) {
      // handleEvent is called once per event type signalled
      unsigned newMask = 0;
      int nset = 0;
      if (FD_ISSET(fd, &inFd))
      {
        newMask |= src->handleEvent(ReadableEvent);
        ++nset;
      }
      if (FD_ISSET(fd, &outFd))
      {
        newMask |= src->handleEvent(WritableEvent);
        ++nset;
      }
      if (FD_ISSET(fd, &excFd))
      {
        newMask |= src->handleEvent(Exception);
        ++nset;
      }

      // Some event occurred
      if (nset)
      {
        if (newMask)
          thisIt->getMask() = newMask;
        else       // Stop monitoring this one
        {
          _sources.erase(thisIt);
          if ( ! src->getKeepOpen())
            src->close();
        }
      }
    }
  }
#endif

  return true;
}

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).

Definition at line 84 of file XmlRpcDispatch.cc.

Referenced by XmlRpc::XmlRpcClient::execute(), and XmlRpc::XmlRpcServer::work().

{
  // Compute end time
  double timeNow = getTime();
  _endTime = (timeout < 0.0) ? -1.0 : (timeNow + timeout);
  _doClear = false;
  _inWork = true;

  // Only work while there is something to monitor
  while (_sources.size() > 0) {

    // Wait for and dispatch events
    if ( ! waitForAndProcessEvents(timeout))
    {
      _inWork = false;
      return;
    }


    // Check whether to clear all sources
    if (_doClear)
    {
      SourceList closeList = _sources;
      _sources.clear();
      for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it) {
        XmlRpcSource *src = it->getSource();
        src->close();
      }

      _doClear = false;
    }

    // Check whether end time has passed or exit has been called
    if (_endTime == 0.0)        // Exit
      break;
    else if (_endTime > 0.0)    // Check for timeout
    {
      double t = getTime();
      if (t > _endTime)
        break;

      // Decrement timeout by elapsed time
      timeout -= (t - timeNow);
      if (timeout < 0.0)
        timeout = 0.0;    // Shouldn't happen but its fp math...
      timeNow = t;
    }
  }

  _inWork = false;
}


Member Data Documentation

Definition at line 93 of file XmlRpcDispatch.h.

Referenced by clear(), work(), and XmlRpcDispatch().

Definition at line 91 of file XmlRpcDispatch.h.

Referenced by exit(), waitForAndProcessEvents(), work(), and XmlRpcDispatch().

Definition at line 94 of file XmlRpcDispatch.h.

Referenced by clear(), work(), and XmlRpcDispatch().


The documentation for this class was generated from the following files: