예제 #1
0
void XmlRpcDispatch::processFds (short revents, SourceList::iterator thisIt, XmlRpcSource *chunkWait)
{
	XmlRpcSource* src = thisIt->getSource();
	unsigned newMask = (unsigned) -1;
	// If you select on multiple event types this could be ambiguous
	try
	{
		if (revents & (POLLIN | POLLPRI))
			newMask &= (src == chunkWait) ? src->handleChunkEvent(ReadableEvent) : src->handleEvent(ReadableEvent);
	}
	catch (const XmlRpcAsynchronous &async)
	{
		XmlRpcUtil::log(3, "Asynchronous event while handling response.");
		// stop monitoring the source..
		thisIt->getMask() = 0;
		src->goAsync ();
	}

	if (revents & POLLOUT)
		newMask &= (src == chunkWait) ? src->handleChunkEvent(WritableEvent) : src->handleEvent(WritableEvent);
	if (revents & (POLLRDHUP | POLLERR | POLLHUP | POLLNVAL))
		newMask &= (src == chunkWait) ? src->handleChunkEvent(Exception) : src->handleEvent(Exception);

	if ( ! newMask)
	{
		// Stop monitoring this one
		_sources.erase(thisIt);
		if ( ! src->getKeepOpen())
			src->close();
	}
	else if (newMask != (unsigned) -1)
	{
		thisIt->getMask() = newMask;
	}
}
예제 #2
0
void XmlRpcDispatch::addToFd (void (*addFD) (int, short))
{
	SourceList::iterator it;
	for (it=_sources.begin(); it!=_sources.end(); ++it)
	{
		short events = 0;
		if (it->getMask() & ReadableEvent) events |= POLLIN | POLLPRI;
		if (it->getMask() & WritableEvent) events |= POLLOUT;
		if (it->getMask() & Exception)     events |= POLLRDHUP | POLLERR | POLLHUP | POLLNVAL;
		if (events != 0)
			addFD (it->getSource()->getfd(), events);
	}
}
예제 #3
0
void XmlRpcDispatch::addToFds (struct pollfd *fds, nfds_t &nfd)
{
	SourceList::iterator it;
	for (it=_sources.begin(); it!=_sources.end(); ++it)
	{
		short events = 0;
		if (it->getMask() & ReadableEvent) events |= POLLIN | POLLPRI;
		if (it->getMask() & WritableEvent) events |= POLLOUT;
		if (it->getMask() & Exception)     events |= POLLRDHUP | POLLERR | POLLHUP | POLLNVAL;
		if (events != 0)
		{
			fds[nfd].fd = it->getSource()->getfd();
			fds[nfd].events = events;
			fds[nfd].revents = 0;
			nfd++;	
		}
	}
}
예제 #4
0
// Watch current set of sources and process events
void
XmlRpcDispatch::work(double timeout)
{
  // Compute end time
  _endTime = (timeout < 0.0) ? -1.0 : (getTime() + timeout);
  _doClear = false;
  _inWork = true;

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

    // 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;     // Not used on windows
    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 (timeout < 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)
    {
      XmlRpcUtil::error("Error in XmlRpcDispatch::work: error in select (%d).", nEvents);
      _inWork = false;
      return;
    }

    // Process events
    for (it=_sources.begin(); it != _sources.end(); )
    {
      SourceList::iterator thisIt = it++;
      XmlRpcSource* src = thisIt->getSource();
      int fd = src->getfd();
      unsigned newMask = (unsigned) -1;
      if (fd <= maxFd) {
        // If you select on multiple event types this could be ambiguous
        if (FD_ISSET(fd, &inFd))
          newMask &= src->handleEvent(ReadableEvent);
        if (FD_ISSET(fd, &outFd))
          newMask &= src->handleEvent(WritableEvent);
        if (FD_ISSET(fd, &excFd))
          newMask &= src->handleEvent(Exception);

        if ( ! newMask) {
          _sources.erase(thisIt);  // Stop monitoring this one
          if ( ! src->getKeepOpen())
            src->close();
        } else if (newMask != (unsigned) -1) {
          thisIt->getMask() = newMask;
        }
      }
    }

    // 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
    if (0 <= _endTime && getTime() > _endTime)
      break;
  }

  _inWork = false;
}
예제 #5
0
// Watch current set of sources and process events
void
XmlRpcDispatch::work(double timeout_in_seconds)
{
  // Compute end time
    _endTime = (timeout_in_seconds < 0.0) ? -1.0 : (getTime() + timeout_in_seconds);
  _doClear = false;
  _inWork = true;

  // Only work while there is something to monitor
  while (_sources.size() > 0) {
      // // 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;     // Not used on windows
      //    SourceList::iterator it;
    int fds_size = _sources.size();
    std::vector<struct pollfd> fds(fds_size);

    {

        int __offset = 0;
        for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
        {
            fds[__offset].fd = it->getSource()->getfd();
            fds[__offset].events = 0;
            fds[__offset].revents = 0;
            if (it->getMask() & ReadableEvent) fds[__offset].events |= POLLIN;
            if (it->getMask() & WritableEvent) fds[__offset].events |= POLLOUT;
            if (it->getMask() & Exception)     fds[__offset].events |= POLLERR;
            //  2      if (it->getMask() && fd > maxFd)   maxFd = fd;
            ++__offset;
        }
    }

    // Check for events
    returnhereoninterruptedsyscall:
    int nEvents;
    if (timeout_in_seconds < 0.0)
        nEvents = poll(&fds[0], fds_size, -1);
    else
    {
        nEvents = poll(&fds[0],fds_size, timeout_in_seconds * 1000);
    }
    if(nEvents == -1 and errno == EINTR)
        goto returnhereoninterruptedsyscall;

    if (nEvents < 0)
    {
        LOG_ERROR("Error in XmlRpcDispatch::work: error in select " <<  strerror(errno));
       //        LOG_ERROR(strerror(errno));

//        XmlRpcUtil::error("Error in XmlRpcDispatch::work: error in select (%d).", nEvents);
        _inWork = false;
        return;
    }

    // Process events
    {

        size_t __offset = 0;

        for (SourceList::iterator it = _sources.begin(); it != _sources.end(); )
        {
            SourceList::iterator thisIt = it++;
            XmlRpcSource* src = thisIt->getSource();
            unsigned newMask = (unsigned) -1;

            // accepting a new connection (XmlRpcServer::handleEvent)
            // will add a new entry to _sources but we don't have an
            // entry in the fds around.
            if (__offset < fds.size())
            {
                assert(fds[__offset].fd == src->getfd());
                // if (fd <= maxFd)
                // {
                // If you select on multiple event types this could be ambiguous
                if (fds[__offset].revents bitand POLLIN)
                {
                    newMask &= src->handleEvent(ReadableEvent);
                }
                if (fds[__offset].revents bitand POLLOUT)
                {
                    newMask &= src->handleEvent(WritableEvent);
                }
                if (fds[__offset].revents bitand POLLERR)
                {
                    newMask &= src->handleEvent(Exception);
                }
            }

            if (newMask == 0)
            {
                _sources.erase(thisIt);  // Stop monitoring this one
                if (!src->getKeepOpen())
                {
                    src->close();
                }

            }
            else if (newMask != (unsigned) -1)
            {
                thisIt->getMask() = newMask;
            }
            __offset++;
        }
    }

    // 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
    if (0 <= _endTime && getTime() > _endTime)
      break;
  }

  _inWork = false;
}