fdwatch_epoll.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.   * Abstraction API/layer for the various ways PvPGN can inspect sockets state
  3.   * 2003 (C) dizzy@roedu.net
  4.   *
  5.   * Code is based on the ideas found in thttpd project.
  6.   *
  7.   * Linux epoll(4) based backend
  8.   *
  9.   * This program is free software; you can redistribute it and/or
  10.   * modify it under the terms of the GNU General Public License
  11.   * as published by the Free Software Foundation; either version 2
  12.   * of the License, or (at your option) any later version.
  13.   *
  14.   * This program is distributed in the hope that it will be useful,
  15.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.   * GNU General Public License for more details.
  18.   *
  19.   * You should have received a copy of the GNU General Public License
  20.   * along with this program; if not, write to the Free Software
  21.   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.   */
  23. #include "common/setup_before.h"
  24. #ifdef HAVE_EPOLL
  25. #ifdef STDC_HEADERS
  26. # include <stdlib.h>
  27. #else
  28. # ifdef HAVE_MALLOC_H
  29. #  include <malloc.h>
  30. # endif
  31. #endif
  32. #ifdef HAVE_STRING_H
  33. # include <string.h>
  34. #else
  35. # ifdef HAVE_STRINGS_H
  36. #  include <strings.h>
  37. # endif
  38. #endif
  39. #ifdef HAVE_SYS_EPOLL_H
  40. # include "compat/uint.h"
  41. # include <sys/epoll.h>
  42. #endif
  43. #include "fdwatch.h"
  44. #include "common/eventlog.h"
  45. #include "common/setup_after.h"
  46. static int sr;
  47. static int epfd;
  48. static struct epoll_event *epevents  = NULL; /* events to investigate */
  49. static struct epoll_event tmpev;
  50. static int fdw_epoll_init(int nfds);
  51. static int fdw_epoll_close(void);
  52. static int fdw_epoll_add_fd(int fd, t_fdwatch_type rw);
  53. static int fdw_epoll_del_fd(int fd);
  54. static int fdw_epoll_watch(long timeout_msecs);
  55. static void fdw_epoll_handle(void);
  56. t_fdw_backend fdw_epoll = {
  57.     fdw_epoll_init,
  58.     fdw_epoll_close,
  59.     fdw_epoll_add_fd,
  60.     fdw_epoll_del_fd,
  61.     fdw_epoll_watch,
  62.     fdw_epoll_handle
  63. };
  64. static int fdw_epoll_init(int nfds)
  65. {
  66.     if ((epfd = epoll_create(nfds)) < 0)
  67. return -1;
  68.     epevents = (struct epoll_event *) malloc(sizeof(struct epoll_event) * nfds);
  69.     if (epevents == NULL)
  70.     {
  71. fdw_epoll_close();
  72. return -1;
  73.     }
  74.     memset(epevents, 0, sizeof(struct epoll_event) * nfds);
  75.     sr = 0;
  76.     eventlog(eventlog_level_info, __FUNCTION__, "fdwatch epoll() based layer initialized (max %d sockets)", nfds);
  77.     return 0;
  78. }
  79. static int fdw_epoll_close(void)
  80. {
  81.     if (epevents != NULL)
  82. free((void *) epevents);
  83.     sr = 0;
  84.     return 0;
  85. }
  86. static int fdw_epoll_add_fd(int fd, t_fdwatch_type rw)
  87. {
  88.     int op;
  89. //    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
  90.     tmpev.events = 0;
  91.     if (rw & fdwatch_type_read)
  92. tmpev.events |= EPOLLIN;
  93.     if (rw & fdwatch_type_write)
  94. tmpev.events |= EPOLLOUT;
  95.     if (fdw_rw[fd]) op = EPOLL_CTL_MOD;
  96.     else op = EPOLL_CTL_ADD;
  97.     tmpev.data.fd = fd;
  98.     if (epoll_ctl(epfd, op, fd, &tmpev)) {
  99. eventlog(eventlog_level_error, __FUNCTION__, "got error from epoll_ctl()");
  100. return -1;
  101.     }
  102.     return 0;
  103. }
  104. static int fdw_epoll_del_fd(int fd)
  105. {
  106. //    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
  107.     if (sr > 0) 
  108. eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");
  109.     if (fdw_rw[fd]) {
  110. tmpev.events = 0;
  111. tmpev.data.fd = fd;
  112. if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &tmpev)) {
  113.     eventlog(eventlog_level_error, __FUNCTION__, "got error from epoll_ctl()");
  114.     return -1;
  115. }
  116.     }
  117.     return 0;
  118. }
  119. static int fdw_epoll_watch(long timeout_msec)
  120. {
  121.     return (sr = epoll_wait(epfd, epevents, fdw_maxfd, timeout_msec));
  122. }
  123. static void fdw_epoll_handle(void)
  124. {
  125.     register unsigned i;
  126. //    eventlog(eventlog_level_trace, __FUNCTION__, "called");
  127.     for (i = 0; i < sr; i++)
  128.     {
  129. //      eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE);
  130. if (fdw_rw[epevents[i].data.fd] & fdwatch_type_read && epevents[i].events & EPOLLIN)
  131.     if (fdw_hnd[epevents[i].data.fd] (fdw_data[epevents[i].data.fd], fdwatch_type_read) == -2)
  132. continue;
  133. if (fdw_rw[epevents[i].data.fd] & fdwatch_type_write && epevents[i].events & EPOLLOUT)
  134.     fdw_hnd[epevents[i].data.fd] (fdw_data[epevents[i].data.fd], fdwatch_type_write);
  135.     }
  136.     sr = 0;
  137. }
  138. #endif /* HAVE_EPOLL */