sock_ev——linux平台socket事件框架(event loop)

来源:互联网 发布:windows ad域的作用 编辑:程序博客网 时间:2024/06/04 01:08

上一篇我们封装了三种事件监听方式,如果分别提供给客户端使用,有点不方便,也不利于统一管理;我们再封装一层EventLoop。

/******************************************************************************************************************************************************************************** FILE: event_loop.h* Description: *  * Copyright (c) 2012 by Liu Yanyun(E-mail:liuyun827@foxmail.com). All Rights Reserved.*            Without permission, shall not be used for any commercial purpose* * History:* VersionName       DateDescription   0.1Liu Yanyun2012/12/20Initial Version   ********************************************************************************************************************************************************************************/#ifndef _EVENT_LOOP_H_#define _EVENT_LOOP_H_#include <string.h>#include <stdint.h>#include <sys/select.h>#include <sys/time.h>#include <sys/types.h>#include <sys/epoll.h>#include <unistd.h>#include <poll.h>#include "sock_ev.h"class Socket;class EventDispatcher;/*==================================================================* Function: EventLoop* Description: event loop,it is adapter for select poll epoll wait event==================================================================*/class EventLoop{public:  /*==================================================================  * Function: EventLoop.EventLoop  * Description: construction function  ==================================================================*/  EventLoop();  /*==================================================================  * Function: EventLoop.~EventLoop  * Description: Destructor function  ==================================================================*/  virtual ~EventLoop();  /*==================================================================  * Function: EventLoop.initialize  * Description: initialize the loop  * Input Para: type_--dispatcher type  * Return Value: success return true,or else return false  ==================================================================*/  bool initialize(LoopType type_);  /*==================================================================  * Function: EventLoop.addEvt  * Description: add an event and register callback  * Input Para:   * Output Para:   * Return Value: success return true,or else return false  ==================================================================*/  bool addEvt(Socket *sock_,      EvCallBack cb_,      EventType evt_,      void *arg_);  /*==================================================================  * Function: EventLoop.removeEvt  * Description: remove an event and un-register callback  * Input Para:   * Output Para:   * Return Value: success return true,or else return false  ==================================================================*/  bool removeEvt(Socket *sock_,      EventType evt_);  /*==================================================================  * Function: EventLoop.listen  * Description: wait for event trigger  * Input Para:   * Output Para:   * Return Value:   ==================================================================*/  int listen(int timeout_);      private:    EventDispatcher *dispatcher;    SockMapT  sockMap;};#endif /*_EVENT_LOOP_H_*/


 

#include "event_loop.h"#include "sock_ev.h"#include "event_dispatcher.h"#include "socket_base.h"#include "socket.h"EventLoop::EventLoop(){  dispatcher = NULL;}EventLoop::~EventLoop(){  if(NULL != dispatcher) delete dispatcher;  sockMap.clear();}bool EventLoop::initialize(LoopType type_){  if(selectLoop == type_)  {    dispatcher = new SelectDispatcher();  }  else if(pollLoop == type_)  {    dispatcher = new PollDispatcher();  }  else if(epollLoop == type_)  {    dispatcher = new EpollDispatcher();  }  else  {    logTrace("loop type is not right:%d", type_);    return false;  }  if(NULL == dispatcher)  {    logTrace("new EventDispatcher is failed");    return false;  }  if(!dispatcher->initialize())  {    logTrace("dispatcher->initialize() is failed");    return false;  }  return true;}bool EventLoop::addEvt(Socket *sock_,    EvCallBack cb_,    EventType evt_,    void *arg_){  if((NULL == sock_) || (-1 == sock_->getFd()) || (NULL == cb_))  {    logTrace("addEvt input is not valid,pleace check");    return false;  }  if(!dispatcher->addEvt(this, sock_, cb_, evt_, arg_))  {    logTrace("addEvt event to loop is failed");    return false;  }  sockMap[sock_->getFd()] = sock_;  return true;}bool EventLoop::removeEvt(Socket *sock_,    EventType evt_){  if((NULL == sock_) || (-1 == sock_->getFd()))  {    logTrace("removeEvt input is not valid,pleace check");    return false;  }  dispatcher->removeEvt(sock_, evt_);  EventType evt = sock_->getEvt();  if(0 == evt)  {    sockMap.erase(sock_->getFd());  }  return true;}int EventLoop::listen(int timeout_){  while(1)  {    dispatcher->listen(sockMap, timeout_);  }}

主要调用前一篇中封装的三种事件监听方式,在初始化的时候选择一种event dipatcher,这就是面向接口编程的好处,利用多态,可以很方便的在运行时进行行为的改变。成员变量sockMap用于保存注册到EventLoop中的socket。