jabberd2  2.5.0
mio_epoll.h
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris, Christof Meerwald
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 /* MIO backend for epoll() */
22 
23 #include <sys/epoll.h>
24 
25 #define MIO_FUNCS \
26  static int _mio_poll(mio_t m, int t) \
27  { \
28  return epoll_wait(MIO(m)->epoll_fd, \
29  MIO(m)->res_event, 32, t*1000); \
30  } \
31  \
32  static mio_fd_t _mio_alloc_fd(mio_t m, int fd) \
33  { \
34  struct epoll_event event; \
35  mio_priv_fd_t priv_fd = malloc(sizeof (struct mio_priv_fd_st)); \
36  memset(priv_fd, 0, sizeof (struct mio_priv_fd_st)); \
37  \
38  priv_fd->mio_fd.fd = fd; \
39  priv_fd->events = 0; \
40  \
41  event.events = priv_fd->events; \
42  event.data.u64 = 0; \
43  event.data.ptr = priv_fd; \
44  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_ADD, fd, &event); \
45  \
46  return (mio_fd_t)priv_fd; \
47  }
48 
49 
50 #define MIO_FD_VARS \
51  uint32_t events;
52 
53 #define MIO_VARS \
54  int defer_free; \
55  int epoll_fd; \
56  struct epoll_event res_event[32];
57 
58 #define MIO_INIT_VARS(m) \
59  do { \
60  MIO(m)->defer_free = 0; \
61  if ((MIO(m)->epoll_fd = epoll_create(maxfd)) < 0) \
62  { \
63  mio_debug(ZONE,"unable to initialize epoll mio"); \
64  free(m); \
65  return NULL; \
66  } \
67  } while(0)
68 
69 #define MIO_FREE_VARS(m) \
70  do { \
71  close(MIO(m)->epoll_fd); \
72  } while(0)
73 
74 
75 #define MIO_ALLOC_FD(m, rfd) _mio_alloc_fd(m, rfd)
76 #define MIO_FREE_FD(m, mfd) if(mfd)free(mfd)
77 
78 #define MIO_REMOVE_FD(m, mfd) \
79  do { \
80  struct epoll_event event; \
81  event.events = 0; \
82  event.data.u64 = 0; \
83  event.data.ptr = mfd; \
84  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_DEL, \
85  mfd->mio_fd.fd, &event); \
86  } while (0)
87 
88 #define MIO_CHECK(m, t) _mio_poll(m, t)
89 
90 #define MIO_SET_READ(m, mfd) \
91  do { \
92  struct epoll_event event; \
93  event.events = mfd->events; \
94  mfd->events |= EPOLLIN; \
95  if( mfd->events == event.events ) \
96  break; \
97  event.events = mfd->events; \
98  event.data.u64 = 0; \
99  event.data.ptr = mfd; \
100  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_MOD, \
101  mfd->mio_fd.fd, &event); \
102  } while (0)
103 
104 #define MIO_SET_WRITE(m, mfd) \
105  do { \
106  struct epoll_event event; \
107  event.events = mfd->events; \
108  mfd->events |= EPOLLOUT; \
109  if( mfd->events == event.events ) \
110  break; \
111  event.events = mfd->events; \
112  event.data.u64 = 0; \
113  event.data.ptr = mfd; \
114  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_MOD, \
115  mfd->mio_fd.fd, &event); \
116  } while (0)
117 
118 #define MIO_UNSET_READ(m, mfd) \
119  do { \
120  struct epoll_event event; \
121  event.events = mfd->events; \
122  mfd->events &= ~EPOLLIN; \
123  if( mfd->events == event.events ) \
124  break; \
125  event.events = mfd->events; \
126  event.data.u64 = 0; \
127  event.data.ptr = mfd; \
128  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_MOD, \
129  mfd->mio_fd.fd, &event); \
130  } while (0)
131 
132 #define MIO_UNSET_WRITE(m, mfd) \
133  do { \
134  struct epoll_event event; \
135  event.events = mfd->events; \
136  mfd->events &= ~(EPOLLOUT); \
137  if( mfd->events == event.events ) \
138  break; \
139  event.events = mfd->events; \
140  event.data.u64 = 0; \
141  event.data.ptr = mfd; \
142  epoll_ctl(MIO(m)->epoll_fd, EPOLL_CTL_MOD, \
143  mfd->mio_fd.fd, &event); \
144  } while (0)
145 
146 
147 #define MIO_CAN_READ(m,iter) \
148  (MIO(m)->res_event[iter].events & (EPOLLIN|EPOLLERR|EPOLLHUP))
149 
150 #define MIO_CAN_WRITE(m,iter) \
151  (MIO(m)->res_event[iter].events & EPOLLOUT)
152 
153 #define MIO_CAN_FREE(m) (!MIO(m)->defer_free)
154 
155 #define MIO_INIT_ITERATOR(iter) \
156  int iter
157 
158 #define MIO_ITERATE_RESULTS(m, retval, iter) \
159  for(MIO(m)->defer_free = 1, iter = 0; (iter < retval) || ((MIO(m)->defer_free = 0)); iter++)
160 
161 #define MIO_ITERATOR_FD(m, iter) \
162  (MIO(m)->res_event[iter].data.ptr)