⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventloop.cpp

📁 SMC takes a state machine stored in a .sm file and generates a State pattern in twelve programming l
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL/// // Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.// // The Original Code is State Machine Compiler (SMC).// // The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2000 - 2007. Charles W. Rapp.// All Rights Reserved.// // Contributor(s): //// Name//	Eventloop.h//// Description//  Encapsulates the select-based event loop and timer table.//// RCS ID// $Id: Eventloop.cpp,v 1.6 2008/02/04 12:45:07 fperrad Exp $//// CHANGE LOG// $Log: Eventloop.cpp,v $// Revision 1.6  2008/02/04 12:45:07  fperrad// fix build on linux (gcc 4.1.3)//// Revision 1.5  2007/12/28 12:34:40  cwrapp// Version 5.0.1 check-in.//// Revision 1.4  2005/05/28 13:31:18  cwrapp// Updated C++ examples.//// Revision 1.0  2003/12/14 19:35:40  charlesr// Initial revision//#include "Eventloop.h"#include <errno.h>#if !defined(WIN32)#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/time.h>#include <sys/resource.h>#endifconst static long USECS_PER_SEC = 1000000;const static long USECS_PER_MSEC = 1000;const static int WIN32_MAX_SOCKET = 1024;//---------------------------------------------------------------// Eventloop() (Public)// Default constructor.//Eventloop::Eventloop(): _continueRunning(1),  _maxFD(-1),  _fdCount(0),  _timerTable(NULL){#if !defined(WIN32)    rlimit limit;#endif    FD_ZERO(&_fdSet);    // Allocate the file descriptor callback table. First, find    // out the max file descriptor value.#if defined(WIN32)    _fdTable = new InputListener*[WIN32_MAX_SOCKET];    (void) memset(_fdTable,                  0,                  (FD_SETSIZE * sizeof(InputListener*)));#else    (void) getrlimit(RLIMIT_NOFILE, &limit);    _fdTable = new InputListener*[limit.rlim_cur];    (void) memset(_fdTable,                  0,                  (limit.rlim_cur * sizeof(InputListener*)));#endif    return;} // end of Eventloop::Eventloop()//---------------------------------------------------------------// ~Eventloop() (Public)// Destructor.//Eventloop::~Eventloop(){    Eventloop::Timer *timerIt,                     *nextTimer;    // Just in case the event loop is still running.    _continueRunning = 0;    if (_fdTable != NULL)    {        delete[] _fdTable;        _fdTable = NULL;    }    for (timerIt = _timerTable;         timerIt != NULL;         timerIt = nextTimer)    {        nextTimer = timerIt->getNext();        timerIt->setNext(NULL);        delete timerIt;    }    return;} // end of Eventloop::~Eventloop()//---------------------------------------------------------------// start() (Public)// Start the event loop running.//int Eventloop::start(){    timeval timeout,            currTime,           *timeoutPtr;    Timer *timer;    fd_set readSet;    int i,        fdCount,        retcode;    TimerListener *listener;    char *timerName;    _continueRunning = 1;    retcode = 0;    while (_continueRunning == 1)    {        // Figure out how long to wait. If there are no timers,        // then set timeoutPtr to NULL and wait forever.        // Otherwise, put the timeout in the timeval struct and        // point timeoutPtr to it.        if (_timerTable == NULL)        {            timeoutPtr = NULL;        }        else        {            // Get the current time and figure out how long until            // the next timeout.            gettime(currTime);            // If we have passed the current timeout value, then            // don't sleep at all.            if (*_timerTable < currTime)            {                timeout.tv_sec = 0;                timeout.tv_usec = 0;            }            else            {                timeout.tv_sec =                    (_timerTable->getExpiration()).tv_sec - currTime.tv_sec;                timeout.tv_usec =                    (_timerTable->getExpiration()).tv_usec - currTime.tv_usec;                // If the microseconds are less than 0, then subtract                // a second and add 1,000,000 microseconds.                if (timeout.tv_usec < 0)                {                    --(timeout.tv_sec);                    timeout.tv_usec += USECS_PER_SEC;                }            }            timeoutPtr = &timeout;        }        // Since select modifies the FD sets, pass in a copy.        FD_ZERO(&readSet);        for (i = 0; i < _maxFD; ++i)        {            if (FD_ISSET(i, &_fdSet))            {#if defined(WIN32)                FD_SET((u_int) i, &readSet);#else                FD_SET(i, &readSet);#endif            }        }        if ((fdCount = select(_maxFD, &readSet, NULL, NULL, timeoutPtr)) < 0)        {            // If select() was interrupted, ignore the error.            if (errno != EINTR)            {                _continueRunning = 0;                retcode = errno;            }        }        else        {            // Issue read events first.            for (i = 0; i < _maxFD && fdCount > 0; ++i)            {                if (FD_ISSET(i, &readSet))                {                    --fdCount;                    if (_fdTable[i] != NULL)                    {                        _fdTable[i]->handleReceive(i);                    }                }            }            // Issue timeouts.            gettime(currTime);            while (_timerTable != NULL &&                   *_timerTable <= currTime)            {                // Remove the timer from the timer table *before*                // issuing the callback 'cause the callback may                // set this same timer again before returning                // (and the set will fail if the timer is already                // in the table).                timer = _timerTable;                _timerTable = timer->getNext();                timer->setNext(NULL);                // Save away the necessary timer info.                listener = &(timer->getListener());                timerName = new char[strlen(timer->getName()) + 1];                strcpy(timerName, timer->getName());                // Now delete the defunct timer.                delete timer;                listener->handleTimeout(timerName);                delete[] timerName;            }        }    }    return(retcode);} // end of Eventloop::start()//---------------------------------------------------------------// stop() (Public)// Stop the event loop.//void Eventloop::stop(){    _continueRunning = 0;    return;} // end of Eventloop::stop()//---------------------------------------------------------------// addFD(int, InputListener&) (Public)// Start watching a file descriptor and route the callback to the// given connection.//void Eventloop::addFD(int fd, InputListener& listener){    if (!FD_ISSET(fd, &_fdSet))    {#if defined(WIN32)        FD_SET((u_int) fd, &_fdSet);#else        FD_SET(fd, &_fdSet);#endif        ++_fdCount;    }    _fdTable[fd] = &listener;    if (fd >= _maxFD)    {        _maxFD = fd + 1;    }    return;} // end of Eventloop::addFD(int, InputListener&)//---------------------------------------------------------------// removeFD(int) (Public)// Stop watching a file descriptor.//void Eventloop::removeFD(int fd){    int i;#if defined(WIN32)    FD_CLR((u_int) fd, &_fdSet);#else    FD_CLR(fd, &_fdSet);#endif    _fdTable[fd] = NULL;    --_fdCount;    // Are we watching any file descriptors?    if (_fdCount == 0)    {        _maxFD = -1;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -