├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── README.md
├── TODO
├── examples
├── test_client.cpp
├── test_echo.cpp
├── test_hsha.cpp
├── test_logger.cpp
└── test_timer.cpp
└── luves
├── buffer.cpp
├── buffer.h
├── channel.cpp
├── channel.h
├── connection.cpp
├── connection.h
├── epoll.cpp
├── epoll.h
├── eventhandle.cpp
├── eventhandle.h
├── hshaserver.cpp
├── hshaserver.h
├── kqueue.cpp
├── kqueue.h
├── logger.cpp
├── logger.h
├── luves.h
├── net.cpp
├── net.h
├── tcpserver.cpp
├── tcpserver.h
├── threadpool.cpp
├── threadpool.h
├── timer.cpp
└── timer.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 | *.smod
19 |
20 | # Compiled Static libraries
21 | *.lai
22 | *.la
23 | *.a
24 | *.lib
25 |
26 | # Executables
27 | *.exe
28 | *.out
29 | *.app
30 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(Luves)
3 |
4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
5 |
6 | set(SOURCE_FILES
7 | examples/test_client.cpp
8 | examples/test_echo.cpp
9 | luves/test_hsha.cpp
10 | examples/test_logger.cpp
11 | examples/test_timer.cpp
12 | luves/buffer.cpp
13 | luves/buffer.h
14 | luves/channel.cpp
15 | luves/channel.h
16 | luves/epoll.cpp
17 | luves/epoll.h
18 | luves/eventhandle.cpp
19 | luves/eventhandle.h
20 | luves/hshaserver.cpp
21 | luves/hshaserver.h
22 | luves/kqueue.cpp
23 | luves/kqueue.h
24 | luves/logger.cpp
25 | luves/logger.h
26 | luves/luves.h
27 | luves/net.cpp
28 | luves/net.h
29 | luves/tcpconnection.cpp
30 | luves/tcpconnection.h
31 | luves/tcpserver.cpp
32 | luves/tcpserver.h
33 | luves/test_hsha.cpp
34 | luves/threadpool.cpp
35 | luves/threadpool.h
36 | luves/timer.cpp
37 | luves/timer.h)
38 |
39 | add_executable(Luves ${SOURCE_FILES})
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Leviathan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CC=g++
2 | CFLAGS=-std=c++11 -fPIC -c
3 | DFLAGS=-std=c++11 -shared
4 | LIBLUVES=libluves.so
5 |
6 | SOURCES=$(shell find luves -name "*.cpp")
7 | OBJ=$(SOURCES:%.cpp=%.o)
8 | PREFIX=luves
9 |
10 | build:$(LIBLUVES)
11 | cp -fr luves /usr/local/include
12 | cp $(LIBLUVES) /usr/local/lib
13 | rm $(PREFIX)/*.o $(LIBLUVES)
14 |
15 | $(LIBLUVES):$(OBJ)
16 | $(CC) $(DFLAGS) -o $@ $(OBJ)
17 |
18 | $(PREFIX)/%.o: $(PREFIX)/%.cpp $(PREFIX)/%.h
19 | $(CC) $(CFLAGS) -c $< -o $@
20 |
21 | clean:
22 | rm $(LIBLUVES)
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Luves
2 |
3 |
4 | [](https://travis-ci.org/Leviathan1995/Luves)
5 |
6 | Luves是一个轻量级的事件触发网络库,封装了Socket,简化基于Socket程序开发。目标是封装了以下三种事件的响应:IO事件,定时器事件,信号事件。支持跨平台,OS X环境使用kqueue模型,Linux环境使用Epoll模型,实现半同步/半异步(HSHA)服务器框架模型。
7 |
8 | - [写在前面][0]
9 | - [安装][1]
10 | - [编译][2]
11 | - [示例][3]
12 | - [测试结果][4]
13 | - [版本更新日志][5]
14 | - [License][6]
15 |
16 |
17 |
18 | ## 写在前面
19 |
20 | 将自己理解的网络框架以"学习"的标准实现,简化复杂网络库的细节部分,实现网络库的本质,必要的地方注释了代码实现思路,欢迎提PR或更好的建议。
21 |
22 |
23 |
24 | ## 安装
25 |
26 | make
27 |
28 |
29 | ## 编译
30 | g++ -std=c++11 test_echo.cpp -L/usr/local/lib -lluves
31 |
32 | ## 示例
33 | 简单的Echo服务器
34 |
35 | #include "luves/luves.h"
36 | using namespace luves;
37 |
38 | Buffer GetInput(const TcpConnectionPtr & conn)
39 | {
40 | return conn->GetInputBuffer();
41 | }
42 |
43 | int main()
44 | {
45 | EventLoop loop;
46 | Ip4Addr server_addr("0.0.0.0", 6543);
47 | TcpServer server(&loop, server_addr);
48 | server.SetReadCb(GetInput);
49 |
50 | server.SetWriteCb([](const TcpConnectionPtr & conn)
51 | {conn->Send(conn->GetInputBuffer());});
52 |
53 | server.RunServer();
54 | loop.loop();
55 | }
56 |
57 | ## Echo测试结果
58 |
59 | - 使用ApacheBench测试:
60 |
61 | @ubuntu:~$ ab -n 10000 -c 10 -k http://0.0.0.0:6543/
62 | - 测试结果:
63 |
64 | Server Software:
65 | Server Hostname: 0.0.0.0
66 | Server Port: 6543
67 |
68 | Document Path: /
69 | Document Length: 0 bytes
70 |
71 | Concurrency Level: 10
72 | Time taken for tests: 2.998 seconds
73 | Complete requests: 10000
74 | Failed requests: 0
75 | Keep-Alive requests: 0
76 | Total transferred: 0 bytes
77 | HTML transferred: 0 bytes
78 | Requests per second: 3335.80 [#/sec] (mean)
79 | Time per request: 2.998 [ms] (mean)
80 | Time per request: 0.300 [ms] (mean, across all concurrent requests)
81 | Transfer rate: 0.00 [Kbytes/sec] received
82 |
83 | Connection Times (ms)
84 | min mean[+/-sd] median max
85 | Connect: 0 0 1.2 0 77
86 | Processing: 0 3 4.6 2 78
87 | Waiting: 0 0 0.0 0 0
88 | Total: 1 3 4.7 2 79
89 |
90 | ## 版本更新日志
91 | Version 0.01
92 |
93 | - 原型开发,目前使用kqueue,暂支持OS X系统,实现半同步半异步服务器框架.封装了IO事件与定时事件。
94 | - 实现跨平台,添加Linux平台的Epoll模块。
95 | - 修复多线程日志bug
96 | - 修复Hsha模式下kqueue模块bug
97 |
98 |
99 | ## License
100 | MIT
101 |
102 | [0]:#title00
103 | [1]:#title01
104 | [2]:#title02
105 | [3]:#title03
106 | [4]:#title04
107 | [5]:#title05
108 | [6]:#title06
109 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/test_client.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // echo_client.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/5/26.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | /*
10 | #include "luves.h"
11 |
12 | using namespace luves;
13 |
14 | int main()
15 | {
16 | EventLoop * loop;
17 | Ip4Addr server_addr("127.0.0.1",1234);
18 | TcpClient client(loop,server_addr);
19 | client.SetReadCb([](const TcpConnectionPtr & conn)
20 | {conn->Send(conn->GetInputBuffer());});
21 | loop->loop();
22 | return 0;
23 | }
24 | */
25 |
--------------------------------------------------------------------------------
/examples/test_echo.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // echo.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/5/19.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 |
10 | #include "luves/luves.h"
11 |
12 | using namespace luves;
13 |
14 | Buffer GetInput(const TcpConnectionPtr & conn)
15 | {
16 | return conn->GetInputBuffer();
17 | }
18 |
19 | int main()
20 | {
21 | EventLoop loop;
22 | Ip4Addr server_addr("0.0.0.0", 6543);
23 | TcpServer server(&loop, server_addr);
24 | server.SetReadCb(GetInput);
25 |
26 |
27 | /*
28 | server.SetWriteCb([](const TcpConnectionPtr & conn)
29 | {conn->Send("HTTP/1.1 200 OK\r\n"
30 | "Content-Type:text/html;charset=utf-8\r\n"
31 | "Content-Length:18\r\n"
32 | "\r\n"
33 | "Welcome to tinyweb");});
34 | */
35 | server.SetWriteCb([](const TcpConnectionPtr & conn)
36 | {conn->Send(conn->GetInputBuffer());});
37 |
38 | server.RunServer();
39 | loop.loop();
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/examples/test_hsha.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // test_hsha.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/6/28.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | /*
10 | #include "luves.h"
11 |
12 | using namespace luves;
13 |
14 | Buffer GetInput(const TcpConnectionPtr & conn)
15 | {
16 | return conn->GetInputBuffer();
17 | }
18 |
19 | int main()
20 | {
21 | EventLoop loop;
22 | Ip4Addr server_addr("0.0.0.0", 6543);
23 |
24 | HshaServer server(&loop, server_addr, 2);
25 | server.SetReadCb(GetInput);
26 |
27 |
28 | server.SetWriteCb([](const TcpConnectionPtr & conn)
29 | {conn->Send(conn->GetInputBuffer());});
30 |
31 | server.RunServer();
32 | loop.loop();
33 | }
34 | */
35 |
--------------------------------------------------------------------------------
/examples/test_logger.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // log_test.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/6/20.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | /*
10 | #include
11 | #include "luves.h"
12 |
13 | using namespace luves;
14 |
15 | int main()
16 | {
17 | trace("trace test %d%s%s",22,"s","w");
18 | fatal("fatal test");
19 | fatalif(1,"fataif test");
20 | check(1, "check test");
21 | //exitif(1, "exitif test");
22 | fatalif(-1,"-1");
23 | fatalif(0,"0");
24 | }
25 | */
26 |
--------------------------------------------------------------------------------
/examples/test_timer.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // timer.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/6/11.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | /*
10 | #include "luves.h"
11 |
12 | using namespace luves;
13 |
14 | void TimerFunc()
15 | {
16 | std::cout<<"hello world! 10s"<0)
41 | read_index_ += n;
42 |
43 | return n;
44 | }
45 |
46 | int Buffer::WriteImp(int fd) // out
47 | {
48 | int n = int(write(fd, buffer_.data(), write_index_));
49 | INFO_LOG("Write %d bytes.", n);
50 | buffer_.clear();
51 | write_index_ = 0;
52 | return n;
53 | }
54 |
55 | std::ostream & operator <<(std::ostream & os, Buffer & buffer)
56 | {
57 | for (auto data:buffer.buffer_)
58 | os<
13 | #include
14 | #include
15 | #include
16 |
17 | #include "logger.h"
18 |
19 | namespace luves {
20 |
21 | //
22 | //buffer
23 | //
24 | class Buffer
25 | {
26 |
27 | public:
28 | Buffer():read_index_(0),write_index_(0){buffer_.resize(1024);};
29 | ~Buffer(){};
30 |
31 | void Swap(Buffer & rhs)
32 | {
33 | buffer_.swap(rhs.buffer_);
34 | std::swap(read_index_, rhs.read_index_);
35 | std::swap(write_index_,rhs.write_index_);
36 | }
37 |
38 | size_t Capacity(){return buffer_.capacity();}
39 |
40 | size_t Size(){return buffer_.size();}
41 |
42 | void Append(Buffer & buffer);
43 | void Append(const std::string & msg);
44 |
45 | int ReadImp(int fd);
46 | int WriteImp(int fd);
47 |
48 | void Clear(){buffer_.clear();}
49 |
50 | friend std::ostream & operator <<(std::ostream & os,Buffer &buffer);
51 |
52 | std::vector & GetData(){return buffer_;}
53 |
54 | size_t GetWriteIndex(){return write_index_;}
55 | size_t GetReadIndex() {return read_index_;}
56 | private:
57 | size_t read_index_;
58 | size_t write_index_;
59 | std::vector buffer_;
60 | };
61 |
62 | }
63 | #endif /* Buffer_h */
64 |
--------------------------------------------------------------------------------
/luves/channel.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // channel.cpp
3 | // Luves
4 | //
5 | // Created by hashdata on 16/9/30.
6 | // Copyright © 2016年 hashdata. All rights reserved.
7 | //
8 |
9 | #include "channel.h"
10 |
11 | //
12 | //事件通道
13 | //
14 | namespace luves {
15 |
16 | Channel::Channel(EventLoop * loop,int fd, bool is_listen)
17 | {
18 | loop_ = loop;
19 | fd_ = fd;
20 | is_listen_ = is_listen;
21 |
22 | if(!is_listen)
23 | {
24 | sockaddr_in local,peer;
25 | socklen_t len=sizeof(local);
26 | int ret=getsockname(fd_, (struct sockaddr*)&local, &len);
27 | if (ret<0)
28 | ERROR_LOG("get local addr failed! %d %s", errno, strerror(errno));
29 | ret=getpeername(fd_, (struct sockaddr*)&peer, &len);
30 | if (ret<0)
31 | ERROR_LOG("get peer addr failed! %d %s", errno, strerror(errno));
32 |
33 | Ip4Addr local_addr(local), peer_addr(peer);
34 | connection_ = TcpConnectionPtr(new TcpConnection(loop_, fd_));
35 | SocketOp::SetNonblock(fd_); //设置fd为非阻塞
36 | TRACE_LOG("TCP服务创建成功:%s--%s:%d",local_addr.ToString().c_str(), peer_addr.ToString().c_str(),fd_);
37 |
38 | SetReadCb([this]{GetConnectionPtr()->HandleRead();});
39 | SetWriteCb([this]{GetConnectionPtr()->HandleWrite();});
40 |
41 | }
42 | };
43 |
44 | //关闭通道
45 | void Channel::Close()
46 | {
47 | //清理缓冲区
48 | this->connection_->GetInputBuffer().Clear();
49 | this->connection_->GetOutputBuffer().Clear();
50 | loop_->DeleteChannel(this);
51 | }
52 |
53 | void Channel::HandleEvent()
54 | {
55 | //listen管道
56 | if (is_listen_)
57 | {
58 | if (read_cb_)
59 | {
60 | read_cb_();
61 | return;
62 | }
63 | }
64 |
65 | //非listen管道
66 | if(!is_listen_)
67 | {
68 | if (read_cb_)
69 | read_cb_();
70 | if (write_cb_)
71 | write_cb_();
72 | }
73 | if(connection_->IsClose())
74 | Close();
75 | else
76 | {
77 | INFO_LOG("Try to re-add %d to kqueue.", this->GetFd());
78 | loop_->AddChannel(this);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/luves/channel.h:
--------------------------------------------------------------------------------
1 | //
2 | // channel.h
3 | // Luves
4 | //
5 | // Created by hashdata on 16/9/30.
6 | // Copyright © 2016年 hashdata. All rights reserved.
7 | //
8 |
9 | #ifndef CHANNEL_H_
10 | #define CHANNEL_H_
11 |
12 | #include
13 | #include "eventhandle.h"
14 | #include "net.h"
15 | #include "connection.h"
16 |
17 | //
18 | //事件通道,接管一个fd
19 | //
20 |
21 | namespace luves {
22 |
23 | class EventLoop;
24 | class TcpConnection;
25 |
26 | typedef std::shared_ptr TcpConnectionPtr;
27 |
28 | class Channel
29 | {
30 | public:
31 | Channel(EventLoop * loop, int fd, bool is_listen);
32 | ~Channel(){};
33 |
34 | //处理事件
35 | void HandleEvent();
36 |
37 | //设置回调函数
38 | void SetReadCb(const std::function & cb){read_cb_ = cb;}
39 | void SetWriteCb(const std::function & cb){write_cb_ = cb;}
40 | //关闭通道
41 | void Close();
42 |
43 | //获取事件描述符
44 | int GetFd(){return fd_;}
45 |
46 | bool GetIsListen(){return is_listen_;}
47 |
48 | TcpConnectionPtr GetConnectionPtr(){return connection_;}
49 | private:
50 | bool is_listen_; //是否为listen监听套接字的channel
51 | EventLoop * loop_;
52 | int fd_; //事件描述符
53 | std::function read_cb_, write_cb_; //读写回调函数
54 | TcpConnectionPtr connection_; //channel管理的连接
55 |
56 | };
57 |
58 | }
59 | #endif /* channel_hpp */
60 |
--------------------------------------------------------------------------------
/luves/connection.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // tcp_connection.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/6/21.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | #include "connection.h"
10 |
11 | namespace luves {
12 |
13 |
14 | //
15 | //TCP连接模块
16 | //
17 |
18 | //写入消息至缓冲区
19 | void TcpConnection::Send(Buffer & msg)
20 | {
21 | output_.Append(msg);
22 | output_.WriteImp(fd_);
23 | }
24 |
25 | void TcpConnection::Send(const std::string & msg)
26 | {
27 | output_.Append(msg);
28 | output_.WriteImp(fd_);
29 | }
30 |
31 | //接收消息
32 | void TcpConnection::HandleRead()
33 | {
34 |
35 | while (1)
36 | {
37 | int n=input_.ReadImp(fd_);
38 | if (n>0)
39 | {
40 | if (readcb_)
41 | readcb_(shared_from_this());
42 | }
43 | else
44 | {
45 | close(fd_);
46 | INFO_LOG("Close %d socket.", fd_);
47 | is_close_ = true;
48 | break;
49 | }
50 | }
51 | }
52 |
53 | //发送消息
54 | void TcpConnection::HandleWrite()
55 | {
56 | if (writecb_)
57 | writecb_(shared_from_this());
58 | }
59 |
60 | void TcpConnection::HandleClose(const TcpConnectionPtr & conn)
61 | {
62 | if (closecb_)
63 | closecb_(shared_from_this());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/luves/connection.h:
--------------------------------------------------------------------------------
1 | //
2 | // tcp_connection.h
3 | // Luves
4 | //
5 | // Created by leviathan on 16/6/21.
6 | // Copyright © 2016年 leviathan. All rights reserved.
7 | //
8 |
9 | #ifndef TCP_CONNECTION_H_
10 | #define TCP_CONNECTION_H_
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "net.h"
18 | #include "buffer.h"
19 | #include "eventhandle.h"
20 | #include "channel.h"
21 | #include "logger.h"
22 |
23 | namespace luves {
24 |
25 | class TcpConnection;
26 | class EventLoop;
27 | class Channel;
28 |
29 | typedef std::shared_ptr TcpConnectionPtr;
30 | typedef std::function TcpCallBack;
31 |
32 | //
33 | //TCP连接服务
34 | //
35 | class TcpConnection:public std::enable_shared_from_this
36 | {
37 | public:
38 |
39 | TcpConnection(EventLoop *loop, int fd):loop_(loop), fd_(fd), is_close_(false){};
40 | ~TcpConnection(){};
41 |
42 | //设置回调函数
43 | void SetReadCb(const TcpCallBack & cb){readcb_=cb;}
44 | void SetWriteCb(const TcpCallBack & cb){writecb_=cb;}
45 | void SetCloseCb(const TcpCallBack & cb){closecb_=cb;}
46 |
47 | //处理读写回调
48 | void HandleRead();
49 | void HandleWrite();
50 | void HandleClose(const TcpConnectionPtr & conn);
51 | //发送数据
52 | void Send(Buffer & msg);
53 | void Send(const std::string & msg);
54 |
55 | //获取读写缓冲区
56 | Buffer & GetInputBuffer(){return input_;}
57 | Buffer & GetOutputBuffer(){return output_;}
58 |
59 | //断开连接
60 | void Close();
61 |
62 | //获取事件循环
63 | EventLoop * GetLoop(){return loop_;};
64 |
65 | bool IsClose(){return is_close_;}
66 | private:
67 | bool is_close_; //连接是否已经断开
68 | int fd_;
69 | TcpCallBack readcb_,writecb_,closecb_;
70 | EventLoop * loop_;
71 | Buffer input_,output_;
72 | };
73 |
74 | }
75 | #endif /* tcp_connection_h */
76 |
--------------------------------------------------------------------------------
/luves/epoll.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // epoll.cpp
3 | // Luves
4 | //
5 | // Created by leviathan on 16/10/2
6 | // Copyright @ 2016 leviathan. All rights reserved
7 | //
8 |
9 | #ifdef __linux__
10 |
11 | #include "epoll.h"
12 |
13 | namespace luves{
14 |
15 | //
16 | // IO复用模型-Epoll
17 | //
18 |
19 |
20 | EpollModel::EpollModel()
21 | {
22 | ep_ = epoll_create(1024);
23 | max_events_ = 1024;
24 | }
25 |
26 | void EpollModel::AddChannel(Channel * channel)
27 | {
28 | struct epoll_event event;
29 | event.data.fd = channel->GetFd();
30 | if(channel->GetIsListen())
31 | {
32 | event.events = EPOLLIN |EPOLLET;
33 |
34 | listen_fd_ = channel->GetFd();
35 | int ret = epoll_ctl(ep_, EPOLL_CTL_ADD, channel->GetFd(), &event);
36 | if(ret == -1)
37 | {
38 | ERROR_LOG("Epoll add file description failed.");
39 | }
40 | }
41 | else
42 | {
43 | event.events = EPOLLIN|EPOLLOUT|EPOLLET;
44 | int ret = epoll_ctl(ep_, EPOLL_CTL_ADD, channel->GetFd(), &event);
45 | if(ret == -1)
46 | {
47 | ERROR_LOG("Epoll add file description failed.");
48 | }
49 |
50 | }
51 | }
52 |
53 | void EpollModel::DeleteChannel(Channel * channel)
54 | {
55 | int ret = epoll_ctl(ep_, EPOLL_CTL_DEL, channel->GetFd(), NULL);
56 | if(ret == -1)
57 | {
58 | ERROR_LOG("Epoll delete file description failed.");
59 | }
60 | }
61 |
62 | void EpollModel::UpdateChannel(Channel * channel)
63 | {
64 |
65 | }
66 |
67 | void EpollModel::RunModel(int64_t wait_time)
68 | {
69 | int nfds = epoll_wait(ep_, trigger_events_, max_events_, -1);
70 | trigger_channel_.clear();
71 | for (int i = 0; i < nfds; ++i)
72 | {
73 | if ((trigger_events_[i].events & EPOLLERR) ||
74 | (trigger_events_[i].events & EPOLLHUP) ||
75 | (!(trigger_events_[i].events & EPOLLIN)))
76 | {
77 | ERROR_LOG("Epoll return error %d %s",errno, strerror(errno));
78 | exit(1);
79 | }
80 | else if((listen_fd_ == trigger_events_[i].data.fd) ||
81 | ((trigger_events_[i].events & EPOLLIN) && (is_hsha_ == false)))
82 | {
83 | trigger_channel_.push_back(channel_fd_->find(int(trigger_events_[i].data.fd))->second);
84 | }
85 | else if(trigger_events_[i].events & EPOLLIN && is_hsha_)
86 | {
87 | ThreadsPool::AddTask(int(trigger_events_[i].data.fd));
88 | }
89 | }
90 | }
91 |
92 | ChannelList & EpollModel::GetTriggerPtr()
93 | {
94 | return trigger_channel_;
95 | }
96 | }
97 |
98 | #endif /* LINUX */
99 |
--------------------------------------------------------------------------------
/luves/epoll.h:
--------------------------------------------------------------------------------
1 | //
2 | // kqueue.h
3 | // Luves
4 | //
5 | // Created by hashdata on 16/9/30.
6 | // Copyright © 2016年 hashdata. All rights reserved.
7 | //
8 |
9 | #ifdef __linux__
10 |
11 | #ifndef EPOLL_H_
12 | #define EPOLL_H_
13 |
14 | #include
15 | #include
16 | #include
17 | #include