Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46275
  • 博文数量: 13
  • 博客积分: 1857
  • 博客等级: 上尉
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-05 10:56
文章分类
文章存档

2011年(10)

2010年(3)

最近访客

分类: C/C++

2010-08-25 11:07:33

从头编写高性能服务程序(二)
[转]http://blog.chinaunix.net/u/6889/showart.php?id=2296857

从头编写高性能服务程序9-多进程非阻塞epoll-prefork-hook


 

整个基础结构已经基本确定了
接下来做一些细节工作
首先把一些函数抽取出来.
例如prefork独立出来.socket->bind->listen独立出来

这里我们引入一个新的思路
原先由统一的函数在epoll_wait之后对events里面的fd进行处理
但是每个fd可能需要处理的方式都不同.
怎么样针对不同的fd来调用特定的函数呢?

首先在epoll_event结构中有data成员
而data的定义如下

typedef union epoll_data {
                void *ptr;
                int fd;
                __uint32_t u32;
                __uint64_t u64;
        } epoll_data_t;

        struct epoll_event {
                __uint32_t events;      /* Epoll events */
                epoll_data_t data;      /* User data variable */
        };

可见既可以在events里面放data.fd
也可以使用data.ptr来指向一个指针
当fd有消息时内核将对应的ev变量塞入events数组的时候
如果我们只是用fd来指向注册的,那么获取数据的时候只能得到对应的fd
这样使用什么函数来处理这个fd就需要另行判断

那么如果使用ptr来指向一个结构
而结构内保存了fd以及处理这个fd所使用的函数指针
那当我们得到events数组内的事件时
就可以直接调用ptr指向的函数指针了.
这就类似Nginx中的hook函数.
在Nginx中几乎任何一种事件都会绑定其处理函数
而由模块实现距离的函数,然后在hook上去.

那么下面的代码我们就模拟这个方法:
我们建立一个数据结构来保存每个fd以及对应的处理函数

struct event_handle{
    int fd;
    int (* handle)(int fd);
};

handle_hook是我们为每个fd注册的处理函数
当accept获得新的accept_fd之后
我们使用

ev_handles[accept_handles].handle = handle_hook

来将对应的函数注册到对应的events内
在fd得到通知的时候
使用

(*current_handle)(current_fd)

来进行处理

下载:
  1. #include <sys/socket.h>
  2. #include <sys/wait.h>
  3. #include <netinet/in.h>
  4. #include <sys/epoll.h>
  5. #include <sys/sendfile.h> 
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <strings.h>
  11. #include <fcntl.h>
  12. int create_listen_fd(int port){
  13.     int listen_fd;
  14.     struct sockaddr_in my_addr;
  15.     if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
  16.         perror("create socket error");
  17.         exit(1);
  18.     }
  19.     int flag;
  20.     if (setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR
  21.     ,(char *)&flag,sizeof(flag)) == -1){
  22.         perror("setsockopt error");
  23.     }
  24.     int flags = fcntl(listen_fd, F_GETFL, 0);
  25.     fcntl(listen_fd, F_SETFL, flags|O_NONBLOCK);
  26.     my_addr.sin_family = AF_INET;
  27.     my_addr.sin_port = htons(port);
  28.     my_addr.sin_addr.s_addr = INADDR_ANY;
  29.     bzero(&(my_addr.sin_zero), 8);
  30.     if (bind(listen_fd, (struct sockaddr *)&my_addr,
  31.     sizeof(struct sockaddr_in)) == -1) {
  32.         perror("bind error");
  33.         exit(1);
  34.     }
  35.     if (listen(listen_fd,1) == -1){
  36.         perror("listen error");
  37.         exit(1);
  38.     }
  39.     return listen_fd;
  40. }
  41. int create_accept_fd(int listen_fd){
  42.     int addr_len = sizeof( struct sockaddr_in );
  43.     struct sockaddr_in remote_addr;
  44.     int accept_fd = accept( listen_fd,
  45.         (struct sockaddr *)&remote_addr, &addr_len );
  46.     int flags = fcntl(accept_fd, F_GETFL, 0);
  47.     fcntl(accept_fd, F_SETFL, flags|O_NONBLOCK);
  48.     return accept_fd;
  49. }
  50. int fork_process(int process_num){
  51.     int i;
  52.     int pid=-1;
  53.     for(i = 0; i < process_num; i++){
  54.         if(pid != 0){
  55.             pid = fork();
  56.         }
  57.     }
  58.     return pid;
  59. }
  60. int handle_normal(int socket_fd){
  61.     char in_buf[1024];
  62.     memset(in_buf, 0, 1024);
  63.     int recv_num = recv( socket_fd, &in_buf, 1024, 0 );
  64.     if( recv_num ==0 ){
  65.         close(socket_fd);
  66.         printf("ProcessID:%d,EPOLLIN,fd:%d,closed\n", getpid(), socket_fd);
  67.     }
  68.     else{
  69.         printf("ProcessID:%d,EPOLLIN,fd:%d,recv:%s\n", getpid(), socket_fd, in_buf);
  70.     }
  71.     return recv_num;
  72. }
  73. int handle_hook(int socket_fd){
  74.     char in_buf[1024];
  75.     memset(in_buf, 0, 1024);
  76.     int recv_num = recv( socket_fd, &in_buf, 1024, 0 );
  77.     if( recv_num ==0 ){
  78.         close(socket_fd);
  79.         printf("ProcessID:%d,EPOLLIN,fd:%d,closed\n", getpid(), socket_fd);
  80.     }
  81.     else{
  82.         printf("ProcessID:%d,EPOLLIN,fd:%d,recv_num:%d;recv:", getpid(), socket_fd, recv_num);
  83.         for (int i = 0; i<recv_num; i++){
  84.         printf("%02x ",in_buf[i]);
  85.         }
  86.         printf("\n");
  87.     }
  88.     return recv_num;
  89. }
  90. struct event_handle{
  91.     int fd;
  92.     int (* handle)(int fd);
  93. };
  94. typedef int (* EVENT_HANDLE)(int);
  95. typedef struct event_handle * EH;
  96. int main(){
  97.     int listen_fd = create_listen_fd(3389);
  98.     int pid = fork_process(3);
  99.     if(pid == 0){
  100.         int accept_handles = 0;
  101.         struct epoll_event ev,events[20];
  102.         int epfd = epoll_create(256);
  103.         int ev_s = 0;
  104.        
  105.         ev.data.fd = listen_fd;
  106.         ev.events = EPOLLIN|EPOLLET;
  107.         epoll_ctl(epfd,EPOLL_CTL_ADD,listen_fd,&ev);
  108.         struct event_handle ev_handles[256];
  109.         for(;;){
  110.             ev_s = epoll_wait( epfd,events, 20, 500 );
  111.             int i = 0;
  112.             for(i = 0; i<ev_s; i++){
  113.                 if(events[i].data.fd == listen_fd){
  114.                     int max_process_accept = 3;
  115.                     if(accept_handles < max_process_accept){
  116.                         accept_handles++;
  117.                         int accept_fd = create_accept_fd(listen_fd);
  118.                         ev_handles[accept_handles].fd = accept_fd;
  119.                         ev_handles[accept_handles].handle = handle_hook;
  120.                         ev.data.ptr = &ev_handles[accept_handles];
  121.                         ev.events = EPOLLIN|EPOLLET;
  122.                         epoll_ctl(epfd,EPOLL_CTL_ADD,accept_fd,&ev);
  123.                         printf("ProcessID:%d,EPOLLIN,fd:%d,accept:%d\n", getpid(), listen_fd, accept_fd);
  124.                     }
  125.                 }
  126.                 else if(events[i].events&EPOLLIN){
  127.                     EVENT_HANDLE current_handle = ((EH)(events[i].data.ptr))->handle;
  128.                     int current_fd = ((EH)(events[i].data.ptr))->fd;
  129.                     if( (*current_handle)(current_fd)  == 0){ 
  130.                         accept_handles--;
  131.                     }
  132.                 }
  133.                 else if(events[i].events&EPOLLOUT){
  134.                     //need add write event process
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     else{
  140.         //manager the process
  141.         int child_process_status;
  142.         wait(&child_process_status);
  143.     }
  144.    
  145.     return 0;
  146. }
从头编写高性能服务程序10-请求解析

最终的形态基本上在上次的结构中就定型了
当然有些细节需要完善
不过基本上用这个结构来写service已经是OK了
那么现在就是继续细化这个结构.用来写个比较靠近实际的应用

有了链接的管理
接下来就是对通讯协议的实现
由于是从头开始写
所以协议也由我们自己来实现
先是对请求的解析
从客户端telnet传送过来的数据
回行是用/r/n结尾的
所以我们不停的接受数据
然后判断数据的最后是否是/r/n
如果是的话.就把它和以前的数据一起拼接起来
然后调用请求分析来解析指令

在event_handle结构中
我们加入了command数组
用来存放每次传输过来的数据
直至遇到以/r/n结尾的数据.然后拼接起来,输出,再清空这个数组
从头再接受新的指令

由于使用了epoll和非阻塞accept_fd
所以每次接受到的数据是零散的
需要将每次recv的数据连续的拼接到一个变量中
这就是command数组存在的理由
而command_pos用来保存的是每次拼接后数组的实际存放数据的量
也可以认为是最后一个数据所在数组中的位置
便于下次拼接

下载:
  1. #include <sys/socket.h>
  2. #include <sys/wait.h>
  3. #include <netinet/in.h>
  4. #include <sys/epoll.h>
  5. #include <sys/sendfile.h> 
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <strings.h>
  11. #include <fcntl.h>
  12. typedef struct event_handle{
  13.     int fd;
  14.     int ( * handle )( struct event_handle * ev );
  15.     char command[1024];
  16.     int command_pos;
  17. } EV,* EH;
  18. typedef int ( * EVENT_HANDLE )( struct event_handle * ev );
  19. int create_listen_fd( int port ){
  20.     int listen_fd;
  21.     struct sockaddr_in my_addr;
  22.     if ( ( listen_fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
  23.         perror( "create socket error" );
  24.         exit( 1 );
  25.     }
  26.     int flag;
  27.     if ( setsockopt( listen_fd, SOL_SOCKET, SO_REUSEADDR
  28.     , ( char * )&flag, sizeof( flag ) ) == -1 ){
  29.         perror( "setsockopt error" );
  30.     }
  31.     int flags = fcntl( listen_fd, F_GETFL, 0 );
  32.     fcntl( listen_fd, F_SETFL, flags|O_NONBLOCK );
  33.     my_addr.sin_family = AF_INET;
  34.     my_addr.sin_port = htons( port );
  35.     my_addr.sin_addr.s_addr = INADDR_ANY;
  36.     bzero( &( my_addr.sin_zero ), 8 );
  37.     if ( bind( listen_fd, ( struct sockaddr * )&my_addr,
  38.     sizeof( struct sockaddr_in ) ) == -1 ) {
  39.         perror( "bind error" );
  40.         exit( 1 );
  41.     }
  42.     if ( listen( listen_fd, 1 ) == -1 ){
  43.         perror( "listen error" );
  44.         exit( 1 );
  45.     }
  46.     return listen_fd;
  47. }
  48. int create_accept_fd( int listen_fd ){
  49.     int addr_len = sizeof( struct sockaddr_in );
  50.     struct sockaddr_in remote_addr;
  51.     int accept_fd = accept( listen_fd,
  52.         ( struct sockaddr * )&remote_addr, &addr_len );
  53.     int flags = fcntl( accept_fd, F_GETFL, 0 );
  54.     fcntl( accept_fd, F_SETFL, flags|O_NONBLOCK );
  55.     return accept_fd;
  56. }
  57. int fork_process( int process_num ){
  58.     int i;
  59.     int pid=-1;
  60.     for( i = 0; i < process_num; i++ ){
  61.         if( pid != 0 ){
  62.             pid = fork();
  63.         }
  64.     }
  65.     return pid;
  66. }
  67. int handle_hook_v2( EH ev ){
  68.     char in_buf[1024];
  69.     memset( in_buf, 0, 1024 );
  70.     int recv_num = recv( ev->fd, &in_buf, 1024, 0 );
  71.     if( recv_num ==0 ){
  72.         printf( "ProcessID:%d, EPOLLIN, fd:%d, closed\n", getpid(), ev->fd );
  73.         printf( "  recved:%s\n", ev->command );
  74.         close( ev->fd );
  75.     }
  76.     else{
  77.         printf( "ProcessID:%d, EPOLLIN, fd:%d, recv_num:%d;recv:", getpid(), ev->fd, recv_num );
  78.         int i;
  79.         for( i = 0; i<recv_num; i++ ){
  80.             printf( "%02x ", in_buf[i] );
  81.         }
  82.         printf( "\n" );
  83.         memcpy( ev->command + ev->command_pos, in_buf, recv_num );
  84.         ev->command_pos += recv_num;
  85.         if( recv_num == 2 && ( !memcmp( &in_buf[recv_num-2], "\r\n", 2 ) ) ){
  86.             printf( "  recved:%s\n", ev->command );
  87.             memset( ev->command, 0, 1024 );
  88.             ev->command_pos = 0;
  89.         }
  90.     }
  91.     return recv_num;
  92. }
  93. int main(){
  94.     int listen_fd = create_listen_fd( 3389 );
  95.     int pid = fork_process( 3 );
  96.     if( pid == 0 ){
  97.         int accept_handles = 0;
  98.         struct epoll_event ev, events[20];
  99.         int epfd = epoll_create( 256 );
  100.         int ev_s = 0;
  101.        
  102.         ev.data.fd = listen_fd;
  103.         ev.events = EPOLLIN|EPOLLET;
  104.         epoll_ctl( epfd, EPOLL_CTL_ADD, listen_fd, &ev );
  105.         struct event_handle ev_handles[256];
  106.         for( ;; ){
  107.             ev_s = epoll_wait( epfd, events, 20, 500 );
  108.             int i = 0;
  109.             for( i = 0; i<ev_s; i++ ){
  110.                 if( events[i].data.fd == listen_fd ){
  111.                     int max_process_accept = 3;
  112.                     if( accept_handles < max_process_accept ){
  113.                         accept_handles++;
  114.                         int accept_fd = create_accept_fd( listen_fd );
  115.                         ev_handles[accept_handles].fd = accept_fd;
  116.                         ev_handles[accept_handles].handle = handle_hook_v2;
  117.                         ev_handles[accept_handles].command_pos = 0;
  118.                         memset( ev_handles[accept_handles].command, 0, 1024 );
  119.                         ev.data.ptr = &ev_handles[accept_handles];
  120.                         ev.events = EPOLLIN|EPOLLET;
  121.                         epoll_ctl( epfd, EPOLL_CTL_ADD, accept_fd, &ev );
  122.                         printf( "ProcessID:%d, EPOLLIN, fd:%d, accept:%d\n", getpid(), listen_fd, accept_fd );
  123.                     }
  124.                 }
  125.                 else if( events[i].events&EPOLLIN ){
  126.                     EVENT_HANDLE current_handle = ( ( EH )( events[i].data.ptr ) )->handle;
  127.                     EH current_event = ( EH )( events[i].data.ptr );
  128.                     if( ( *current_handle )( current_event )  == 0 ){ 
  129.                         accept_handles--;
  130.                     }
  131.                 }
  132.                 else if( events[i].events&EPOLLOUT ){
  133.                     //need add write event process
  134.                 }
  135.             }
  136.         }
  137.     }
  138.     else{
  139.         //manager the process
  140.         int child_process_status;
  141.         wait( &child_process_status );
  142.     }
  143.    
  144.     return 0;
  145. }





从头编写高性能服务程序11-指令处理&sendfile

实现命令的获取之后
现在是增加对command的解析以及对应的反馈
为了做些稍微有意义的事情.我把这个service做的工作定位在以下内容
1.查询文件大小
2.返回文件内容
3.删除文件

协议的格式如下
请求模式:文件名称
例如
1:new.txt

请求模式见源代码中的宏定义

这次代码也对原来的程序作了一定的修改
从丑陋的代码渐渐修改.
希望在最终程序完成的时候
能够有比较好的代码风格

这个版本中有一个bug
就是sendfile只是调用一次
而实际上如果是较大的文件
需要在判断EPLLOUT之后不停的sendfile
直到EAGAIN遇见accept_fd阻塞为止
这样直至下次EPOLLOUT发生
再从上次暂停的位置继续发送
下一个版本中将会有这个BUG的修正

下载:
  1. #include <sys/socket.h>
  2. #include <sys/wait.h>
  3. #include <netinet/in.h>
  4. #include <netinet/tcp.h>
  5. #include <sys/epoll.h>
  6. #include <sys/sendfile.h> 
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <strings.h>
  13. #include <fcntl.h>
  14. #define HANDLE_INFO   1
  15. #define HANDLE_SEND   2
  16. #define HANDLE_DEL    3
  17. #define HANDLE_CLOSE  4
  18. #define MAX_REQLEN          1024
  19. #define MAX_PROCESS_CONN    3
  20. #define FIN_CHAR            0x00
  21. #define SUCCESS  0
  22. #define ERROR   -1
  23. typedef struct event_handle{
  24.     int socket_fd;
  25.     int file_fd;
  26.     char request[MAX_REQLEN];
  27.     int request_len;
  28.     int ( * handle )( struct event_handle * ev );
  29.     int handle_method;
  30. } EV,* EH;
  31. typedef int ( * EVENT_HANDLE )( struct event_handle * ev );
  32. int create_listen_fd( int port ){
  33.     int listen_fd;
  34.     struct sockaddr_in my_addr;
  35.     if( ( listen_fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
  36.         perror( "create socket error" );
  37.         exit( 1 );
  38.     }
  39.     int flag;
  40.     int olen = sizeof(int);
  41.     if( setsockopt( listen_fd, SOL_SOCKET, SO_REUSEADDR
  42.                         , (const void *)&flag, olen ) == -1 ){
  43.         perror( "setsockopt error" );
  44.     }
  45.     flag = 1;
  46.     if( setsockopt( listen_fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &flag, olen ) == -1 ){
  47.         perror( "setsockopt error" );
  48.     }
  49.     int flags = fcntl( listen_fd, F_GETFL, 0 );
  50.     fcntl( listen_fd, F_SETFL, flags|O_NONBLOCK );
  51.     my_addr.sin_family = AF_INET;
  52.     my_addr.sin_port = htons( port );
  53.     my_addr.sin_addr.s_addr = INADDR_ANY;
  54.     bzero( &( my_addr.sin_zero ), 8 );
  55.     if( bind( listen_fd, ( struct sockaddr * )&my_addr,
  56.     sizeof( struct sockaddr_in ) ) == -1 ) {
  57.         perror( "bind error" );
  58.         exit( 1 );
  59.     }
  60.     if( listen( listen_fd, 1 ) == -1 ){
  61.         perror( "listen error" );
  62.         exit( 1 );
  63.     }
  64.     return listen_fd;
  65. }
  66. int create_accept_fd( int listen_fd ){
  67.     int addr_len = sizeof( struct sockaddr_in );
  68.     struct sockaddr_in remote_addr;
  69.     int accept_fd = accept( listen_fd,
  70.         ( struct sockaddr * )&remote_addr, &addr_len );
  71.     int flags = fcntl( accept_fd, F_GETFL, 0 );
  72.     fcntl( accept_fd, F_SETFL, flags|O_NONBLOCK );
  73.     return accept_fd;
  74. }
  75. int fork_process( int process_num ){
  76.     int i;
  77.     int pid=-1;
  78.     for( i = 0; i < process_num; i++ ){
  79.         if( pid != 0 ){
  80.             pid = fork();
  81.         }
  82.     }
  83.     return pid;
  84. }
  85. int init_evhandle(EH ev,int socket_fd,EVENT_HANDLE handle){
  86.     ev->socket_fd = socket_fd;
  87.     ev->handle = handle;
  88.     ev->request_len = 0;
  89.     ev->handle_method = 0;
  90.     memset( ev->request, 0, 1024 );
  91. }
  92. //accept->accept_queue->request->request_queue->output->output_queue
  93. //multi process sendfile
  94. int parse_request(EH ev){
  95.     ev->request_len--;
  96.     *( ev->request + ev->request_len - 1 ) = 0x00;
  97.     int i;
  98.     for( i=0; i<ev->request_len; i++ ){
  99.         if( ev->request[i] == ':' ){
  100.             ev->request_len = ev->request_len-i-1;
  101.             char temp[MAX_REQLEN];
  102.             memcpy( temp, ev->request, i );
  103.             ev->handle_method = atoi( temp );
  104.             memcpy( temp, ev->request+i+1, ev->request_len );
  105.             memcpy( ev->request, temp, ev->request_len );
  106.             break;
  107.         }
  108.     }
  109.     handle_request( ev );
  110.     return SUCCESS;
  111. }
  112. int handle_request(EH ev){
  113.     struct stat file_info;
  114.     switch( ev->handle_method ){
  115.         case HANDLE_INFO:
  116.             ev->file_fd = open( ev->request, O_RDONLY );
  117.             if( ev->file_fd == -1 ){
  118.                 send( ev->socket_fd, "open file failed\n", strlen("open file failed\n"), 0 );
  119.                 return -1;
  120.             }
  121.             fstat(ev->file_fd, &file_info);
  122.             char info[MAX_REQLEN];
  123.             sprintf(info,"file len:%d\n",file_info.st_size);
  124.             send( ev->socket_fd, info, strlen( info ), 0 );
  125.             break;
  126.         case HANDLE_SEND:
  127.             ev->file_fd = open( ev->request, O_RDONLY );
  128.             if( ev->file_fd == -1 ){
  129.                 send( ev->socket_fd, "open file failed\n", strlen("open file failed\n"), 0 );
  130.                 return -1;
  131.             }
  132.             fstat(ev->file_fd, &file_info);
  133.             sendfile( ev->socket_fd, ev->file_fd, 0, file_info.st_size );
  134.             break;
  135.         case HANDLE_DEL:
  136.             break;
  137.         case HANDLE_CLOSE:
  138.             break;
  139.     }
  140.     finish_request( ev );
  141.     return SUCCESS;
  142. }
  143. int finish_request(EH ev){
  144.     close(ev->socket_fd);
  145.     close(ev->file_fd);
  146.     ev->handle_method = -1;
  147.     clean_request( ev );
  148.     return SUCCESS;
  149. }
  150. int clean_request(EH ev){
  151.     memset( ev->request, 0, MAX_REQLEN );
  152.     ev->request_len = 0;
  153. }
  154. int handle_hook_v2( EH ev ){
  155.     char in_buf[MAX_REQLEN];
  156.     memset( in_buf, 0, MAX_REQLEN );
  157.     int recv_num = recv( ev->socket_fd, &in_buf, MAX_REQLEN, 0 );
  158.     if( recv_num ==0 ){
  159.         close( ev->socket_fd );
  160.         return ERROR;
  161.     }
  162.     else{
  163.         //check ifoverflow
  164.         if( ev->request_len > MAX_REQLEN-recv_num ){
  165.             close( ev->socket_fd );
  166.             clean_request( ev );
  167.         }
  168.         memcpy( ev->request + ev->request_len, in_buf, recv_num );
  169.         ev->request_len += recv_num;
  170.         if( recv_num == 2 && ( !memcmp( &in_buf[recv_num-2], "\r\n", 2 ) ) ){
  171.             parse_request(ev);
  172.         }
  173.     }
  174.     return recv_num;
  175. }
  176. int main(){
  177.     int listen_fd = create_listen_fd( 3389 );
  178.     int pid = fork_process( 3 );
  179.     if( pid == 0 ){
  180.         int accept_handles = 0;
  181.         struct epoll_event ev, events[20];
  182.         int epfd = epoll_create( 256 );
  183.         int ev_s = 0;
  184.        
  185.         ev.data.fd = listen_fd;
  186.         ev.events = EPOLLIN|EPOLLET;
  187.         epoll_ctl( epfd, EPOLL_CTL_ADD, listen_fd, &ev );
  188.         struct event_handle ev_handles[256];
  189.         for( ;; ){
  190.             ev_s = epoll_wait( epfd, events, 20, 500 );
  191.             int i = 0;
  192.             for( i = 0; i<ev_s; i++ ){
  193.                 if( events[i].data.fd == listen_fd ){
  194.                     if( accept_handles < MAX_PROCESS_CONN ){
  195.                         accept_handles++;
  196.                         int accept_fd = create_accept_fd( listen_fd );
  197.                         init_evhandle(&ev_handles[accept_handles],accept_fd,handle_hook_v2);
  198.                         ev.data.ptr = &ev_handles[accept_handles];
  199.                         ev.events = EPOLLIN|EPOLLET;
  200.                         epoll_ctl( epfd, EPOLL_CTL_ADD, accept_fd, &ev );
  201.                     }
  202.                 }
  203.                 else if( events[i].events&EPOLLIN ){
  204.                     EVENT_HANDLE current_handle = ( ( EH )( events[i].data.ptr ) )->handle;
  205.                     EH current_event = ( EH )( events[i].data.ptr );
  206.                     if( ( *current_handle )( current_event )  == 0 ){ 
  207.                         accept_handles--;
  208.                     }
  209.                 }
  210.                 else if( events[i].events&EPOLLOUT ){
  211.                     //need add write event process
  212.                 }
  213.             }
  214.         }
  215.     }
  216.     else{
  217.         //manager the process
  218.         int child_process_status;
  219.         wait( &child_process_status );
  220.     }
  221.    
  222.     return SUCCESS;
  223. }


阅读(1320) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~