All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Static Public Member Functions
GpCoreTools::EventLoop Class Reference

Brief description of class still missing. More...

#include <EventLoop.h>

List of all members.

Public Member Functions

void addEvent (Event *event)
void addStream (Stream *s)
Timer::QueueItem * addTimer (Timer *t)
 EventLoop ()
void exec ()
bool isTerminated () const
void terminate ()
 ~EventLoop ()

Static Public Member Functions

static EventLoopinstance ()
static EventLoopmainInstance ()

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

Description of constructor still missing

References addStream(), GpCoreTools::PThread::currentThread(), GpCoreTools::PThread::setEventLoop(), and TRACE.

  {
    TRACE;
    PThread * t=PThread::currentThread();
    if(t) {
      t->setEventLoop(this);
    } else {
      assert(!_mainLoop);
      _mainLoop=this;
    }
    // A way to force poll() to exit immediately
    _eventStream=new EventStream;
    addStream(_eventStream);
    _terminate=false;
  }

Description of destructor still missing

References TRACE.

  {
    TRACE;
    for(int i=_streams.size()-1;i>=0;i--) {
      delete _streams[i];
    }
    for(std::list<Timer::QueueItem *>::iterator it=_timers.begin(); it!=_timers.end(); it++) {
      delete *it;
    }
  }

Member Function Documentation

void GpCoreTools::EventLoop::addEvent ( Event event) [inline]

Referenced by GpCoreTools::EventStream::event().

{_events.push(event);}
void GpCoreTools::EventLoop::addStream ( Stream s) [inline]
Timer::QueueItem * GpCoreTools::EventLoop::addTimer ( Timer t)

References GpCoreTools::EventStream::send().

Referenced by exec(), and GpCoreTools::Timer::start().

  {
    Timer::QueueItem * tq=new Timer::QueueItem(t);
    addTimer(tq);
    // Force poll() to exit immediately
    _eventStream->send(new NewTimerEvent);
    return tq;
  }

References addTimer(), GpCoreTools::Stream::eventTypes(), GpCoreTools::Stream::fileDescriptor(), TRACE, and GpCoreTools::Log::write().

Referenced by main().

  {
    TRACE;
    _terminate=false;
    Log::write(1, "start event loop\n");
    // Init pollfd vector
    pollfd * pfds=(pollfd *)malloc((_streams.size())*sizeof(pollfd));
    for(int i=_streams.size()-1;i>=0;i--) {
      pollfd& pfd=pfds[i];
      Stream& s=*_streams.at(i);
      pfd.fd=s.fileDescriptor();
      pfd.events=s.eventTypes();
      //Log::write(8, "create stream %i events %x (POLLIN=%i, POLLPRI=%i)\n", i, pfd.events, POLLIN, POLLPRI);
    }
    // Main loop
    while(!_terminate) {
      // Calculate next timeout
      Timer::QueueItem * nextTimer=0;
      int timeout;
      if(_timers.size()==0) {
        timeout=-1;
      } else {
        while(!nextTimer && _timers.size()>0) {
          nextTimer=_timers.back();
          if(!nextTimer->timer()) { // Get rid of stopped timers
            _timers.pop_back();
            delete nextTimer;
            nextTimer=0;
          }
        }
        if(nextTimer) {
          timeout=nextTimer->timer()->timeout();
        } else {
          timeout=-1;
        }
      }
      // Wait for next event or timeout
      unsigned int n=_streams.size();
      //Log::write(6, "enter poll %i streams timeout %i\n", n, timeout);
      int nfd=poll(pfds, n, timeout);
      //Log::write(6, "exit poll %i\n", nfd);
      if(nfd==-1) {
        if(errno!=EINTR) {
          Log::write(0, "%s\n", strerror(errno));
        }
        Log::write(1, "stop event loop\n");
        return;
      }
      // Process next timer
      if(nextTimer && nextTimer->timer()) {
        if(nextTimer->timer()->timeout()==0) {
          _timers.pop_back();
          if(nextTimer->timer()->exec() && nextTimer->timer()) {
            addTimer(nextTimer);
          } else {
            delete nextTimer;
          }
        }
      }
      // Process data exchange on fds
      if(nfd>0) {
        for(unsigned int i=0;i<n;i++) {
          _streams.at(i)->event(pfds[i].revents);
        }
      }
      // Process event queue
      while(!_events.empty()) {
        Event * event=_events.front();
        event->exec();
        delete event;
        _events.pop();
      }
      // Update pollfd vector for new streams
      if(_streams.size()>n) {
        unsigned int newN=_streams.size();
        pfds=(pollfd *)realloc(pfds, newN*sizeof(pollfd));
        for(unsigned int i=n;i<newN;i++) {
          Stream& s=*_streams.at(i);
          pollfd& pfd=pfds[i];
          pfd.fd=s.fileDescriptor();
          pfd.events=s.eventTypes();
          //Log::write(8, "enlarge stream %i events %x (POLLIN=%i, POLLPRI=%i)\n", i, pfd.events, POLLIN, POLLPRI);
        }
        n=newN;
      }
      // Remove dead streams
      for(unsigned int i=0;i<n;) {
        if(_streams.at(i)->isActive()) {
          i++;
        } else {
          n--;
          delete _streams.at(i);
          pfds[i].fd=pfds[n].fd;
          pfds[i].events=pfds[n].events;
          _streams.at(i)=_streams.at(n);
          //Log::write(8, "remove stream %i events %x (POLLIN=%i, POLLPRI=%i)\n", i, pfds[i].events, POLLIN, POLLPRI);
        }
      }
      if(n<_streams.size()) _streams.resize(n);
    }
    Log::write(1, "stop event loop\n");
  }
bool GpCoreTools::EventLoop::isTerminated ( ) const [inline]
{return _terminate;}
static EventLoop* GpCoreTools::EventLoop::mainInstance ( ) [inline, static]

Referenced by GpCoreTools::DaemonApplication::childInterrupted().

{return _mainLoop;}

References GpCoreTools::EventStream::send().

Referenced by GpCoreTools::DaemonApplication::childInterrupted(), and GpCoreTools::PThread::stop().

  {
    // Do not use TRACE here because it uses a mutex which can be locked while this function
    // might be called inside a signal exception.
    _terminate=true;
    // Force poll() to exit immediately
    _eventStream->send(new NewTimerEvent);
  }

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines