ffead.server.doc
SelEpolKqEvPrt.cpp
1 /*
2  Copyright 2009-2013, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16 /*
17  * SelEpolKqEvPrt.cpp
18  *
19  * Created on: 30-Dec-2012
20  * Author: sumeetc
21  */
22 
23 #include "SelEpolKqEvPrt.h"
24 
25 SelEpolKqEvPrt::SelEpolKqEvPrt() {
26  logger = Logger::getLogger("SelEpolKqEvPrt");
27 }
28 
29 SelEpolKqEvPrt::~SelEpolKqEvPrt() {
30 }
31 
32 void SelEpolKqEvPrt::initialize(int sockfd)
33 {
34  this->sockfd = sockfd;
35  curfds = 1;
36  #ifdef USE_SELECT
37  fdmax = sockfd; // maximum file descriptor number
38 
39  FD_ZERO(&master); // clear the master and temp sets
40  FD_ZERO(&read_fds);
41  #endif
42  #ifdef USE_EPOLL
43  epoll_handle = epoll_create(MAXDESCRIPTORS);
44  #endif
45  #ifdef USE_KQUEUE
46  kq = kqueue();
47  if (kq == -1)
48  {
49  perror("kqueue");
50  }
51  #endif
52  #ifdef USE_DEVPOLL
53  if((dev_poll_fd = open("/dev/poll", O_RDWR)) <0)
54  {
55  perror("devpoll");
56  }
57  if (fcntl(dev_poll_fd, F_SETFD, FD_CLOEXEC) < 0)
58  {
59  perror("devpoll fcntl");
60  }
61  #endif
62  #ifdef USE_EVPORT
63  if ((port = port_create()) < 0) {
64  perror("port_create");
65  }
66  #endif
67  #ifdef USE_DEVPOLL
68  nfds=1;
69  polled_fds = (struct pollfd *)calloc(1, nfds*sizeof(struct pollfd));
70  polled_fds->fd = descriptor;
71  polled_fds->events = POLLIN | POLLPRI;
72  return;
73  #endif
74  registerForEvent(sockfd);
75 }
76 
77 
78 int SelEpolKqEvPrt::getEvents()
79 {
80  int numEvents = -1;
81  #ifdef USE_SELECT
82  read_fds = master;
83  numEvents = select(fdmax+1, &read_fds, NULL, NULL, NULL);
84  if(numEvents==-1)
85  {
86  perror("select()");
87  }
88  else
89  {
90  return fdmax+1;
91  }
92  #endif
93  #ifdef USE_EPOLL
94  numEvents = epoll_wait(epoll_handle, events, curfds,-1);
95  #endif
96  #ifdef USE_KQUEUE
97  numEvents = kevent(kq, NULL, 0, evlist, MAXDESCRIPTORS, NULL);
98  #endif
99  #ifdef USE_DEVPOLL
100  struct dvpoll pollit;
101  pollit.dp_timeout = -1;
102  pollit.dp_nfds = curfds;
103  pollit.dp_fds = polled_fds;
104  numEvents = ioctl(dev_poll_fd, DP_POLL, &pollit);
105  #endif
106  #ifdef USE_EVPORT
107  uint_t nevents, wevents = 0;
108  //uint_t num = 0;
109  if (port_getn(port, evlist, 0, &wevents, NULL) < 0) return 0;
110  if (0 == wevents) wevents = 1;
111  nevents = wevents;
112  if (port_getn(port, evlist, (uint_t) MAXDESCRIPTORS, &nevents, NULL) < 0) return 0;
113  numEvents = (int)nevents;
114  #endif
115  #ifdef USE_POLL
116  numEvents = poll(polled_fds,nfds,-1);
117  if (numEvents == -1){
118  perror ("poll");
119  exit(0);
120  }
121  #endif
122  return numEvents;
123 }
124 
125 int SelEpolKqEvPrt::getDescriptor(int index)
126 {
127  #ifdef USE_SELECT
128  if(FD_ISSET(index, &read_fds))
129  {
130  return index;
131  }
132  #endif
133  #ifdef USE_EPOLL
134  if(index>-1 && index<sizeof events)
135  {
136  return events[index].data.fd;
137  }
138  #endif
139  #ifdef USE_KQUEUE
140  if(index>-1 && index<(int)(sizeof evlist))
141  {
142  return evlist[index].ident;
143  }
144  #endif
145  #ifdef USE_DEVPOLL
146  return polled_fds[index].fd;
147  #endif
148  #ifdef USE_EVPORT
149  if(index>-1 && index<sizeof evlist)
150  {
151  return (int)evlist[index].portev_object;
152  }
153  #endif
154  #ifdef USE_POLL
155  return polled_fds[index].fd;
156  #endif
157  return -1;
158 }
159 
160 bool SelEpolKqEvPrt::isListeningDescriptor(int descriptor)
161 {
162  if(descriptor==sockfd)
163  {
164  return true;
165  }
166  return false;
167 }
168 
169 bool SelEpolKqEvPrt::registerForEvent(int descriptor)
170 {
171  curfds++;
172  fcntl(descriptor, F_SETFL, fcntl(descriptor, F_GETFD, 0) | O_NONBLOCK);
173  #ifdef USE_SELECT
174  FD_SET(descriptor, &master); // add to master set
175  if (descriptor > fdmax) { // keep track of the max
176  fdmax = descriptor;
177  }
178  #endif
179  #ifdef USE_EPOLL
180  ev.events = EPOLLIN | EPOLLPRI;
181  ev.data.fd = descriptor;
182  if (epoll_ctl(epoll_handle, EPOLL_CTL_ADD, descriptor, &ev) < 0)
183  {
184  perror("epoll");
185  logger << "Error adding to epoll cntl list" << endl;
186  return false;
187  }
188  #endif
189  #ifdef USE_KQUEUE
190  memset(&change, 0, sizeof(change));
191  EV_SET(&change, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
192  kevent(kq, &change, 1, NULL, 0, NULL);
193  #endif
194  #ifdef USE_DEVPOLL
195  struct pollfd poll_fd;
196  poll_fd.fd = descriptor;
197  poll_fd.events = POLLIN;
198  poll_fd.revents = 0;
199  if (write(dev_poll_fd, &poll_fd, sizeof(poll_fd)) < 0) {
200  perror("devpoll");
201  return false;
202  }
203  #endif
204  #ifdef USE_EVPORT
205  if (port_associate(port, PORT_SOURCE_FD, descriptor, POLLIN, NULL) < 0) {
206  perror("port_associate");
207  }
208  #endif
209  #ifdef USE_POLL
210  nfds++;
211  polled_fds = (struct pollfd *)realloc(polled_fds, (nfds+1)*sizeof(struct pollfd));
212  (polled_fds+nfds)->fd = descriptor;
213  (polled_fds+nfds)->events = POLLIN | POLLPRI;
214  #endif
215  return true;
216 }
217 
218 bool SelEpolKqEvPrt::unRegisterForEvent(int descriptor)
219 {
220  if(descriptor<=0)return false;
221  curfds--;
222  #ifdef USE_SELECT
223  FD_CLR(descriptor, &master);
224  #endif
225  #ifdef USE_EPOLL
226  epoll_ctl(epoll_handle, EPOLL_CTL_DEL, descriptor, &ev);
227  #endif
228  #ifdef USE_KQUEUE
229  memset(&change, 0, sizeof(change));
230  EV_SET(&change, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
231  kevent(kq, &change, 1, NULL, 0, NULL);
232  #endif
233  #ifdef USE_DEVPOLL
234  struct pollfd poll_fd;
235  poll_fd.fd = descriptor;
236  poll_fd.events = POLLREMOVE;
237  poll_fd.revents = 0;
238  if (write(dev_poll_fd, &poll_fd, sizeof(poll_fd)) < 0) {
239  perror("devpoll");
240  return false;
241  }
242  #endif
243  #ifdef USE_EVPORT
244  /*if (port_dissociate(port, PORT_SOURCE_FD, descriptor) < 0) {
245  perror("port_dissociate");
246  }*/
247  #endif
248  #ifdef USE_POLL
249  nfds--;
250  memcpy(polled_fds+index,polled_fds+index+1,nfds-index);
251  polled_fds = (struct pollfd *)realloc(polled_fds, nfds*sizeof(struct pollfd));
252  #endif
253  return true;
254 }
255 
256 void SelEpolKqEvPrt::reRegisterServerSock()
257 {
258  #ifdef USE_EVPORT
259  if (port_associate(port, PORT_SOURCE_FD, sockfd, POLLIN, NULL) < 0) {
260  perror("port_associate");
261  }
262  #endif
263 }