... | ... |
@@ -39,7 +39,8 @@ |
39 | 39 |
# 2004-12-19 amd64 transformed in x86_64 (andrei) |
40 | 40 |
# 2005-04-27 alpha support added (andrei) |
41 | 41 |
# 2005-06-01 use $(LOCALBASE) instead of /usr/{local,pkg} (andrei) |
42 |
-# 2006-06-26 numeric OSREL & HAVE_KQUEUE added to the *BSD (andrei) |
|
42 |
+# 2005-06-26 numeric OSREL & HAVE_KQUEUE added to the *BSD (andrei) |
|
43 |
+# 2005-07-04 HAVE_DEVPOLL added to solaris (andrei) |
|
43 | 44 |
|
44 | 45 |
|
45 | 46 |
# check if already included/exported |
... | ... |
@@ -945,6 +946,12 @@ ifeq ($(OS), solaris) |
945 | 946 |
DEFS+= -DUSE_PTHREAD_MUTEX # try pthread sems |
946 | 947 |
found_lock_method=yes |
947 | 948 |
endif |
949 |
+ # check for ver >= 5.7 |
|
950 |
+ ifeq ($(shell [ $(OSREL_N) -gt 5007 ] && echo has_devpoll), has_devpoll) |
|
951 |
+ ifeq ($(NO_DEVPOLL),) |
|
952 |
+ DEFS+=-DHAVE_DEVPOLL |
|
953 |
+ endif |
|
954 |
+ endif |
|
948 | 955 |
ifeq ($(NO_SELECT),) |
949 | 956 |
DEFS+=-DHAVE_SELECT |
950 | 957 |
endif |
... | ... |
@@ -33,6 +33,7 @@ |
33 | 33 |
* -------- |
34 | 34 |
* 2005-06-15 created by andrei |
35 | 35 |
* 2005-06-26 added kqueue (andrei) |
36 |
+ * 2005-07-04 added /dev/poll (andrei) |
|
36 | 37 |
*/ |
37 | 38 |
|
38 | 39 |
|
... | ... |
@@ -42,6 +43,12 @@ |
42 | 43 |
#ifdef HAVE_EPOLL |
43 | 44 |
#include <unistd.h> /* close() */ |
44 | 45 |
#endif |
46 |
+#ifdef HAVE_DEVPOLL |
|
47 |
+#include <sys/types.h> /* open */ |
|
48 |
+#include <sys/stat.h> |
|
49 |
+#include <fcntl.h> |
|
50 |
+#include <unistd.h> /* close, ioctl */ |
|
51 |
+#endif |
|
45 | 52 |
|
46 | 53 |
#include <sys/utsname.h> /* uname() */ |
47 | 54 |
#include <stdlib.h> /* strtol() */ |
... | ... |
@@ -195,8 +202,10 @@ static void destroy_sigio(io_wait_h* h) |
195 | 202 |
* returns -1 on error, 0 on success */ |
196 | 203 |
static int init_epoll(io_wait_h* h) |
197 | 204 |
{ |
205 |
+again: |
|
198 | 206 |
h->epfd=epoll_create(h->max_fd_no); |
199 | 207 |
if (h->epfd==-1){ |
208 |
+ if (errno==EINTR) goto again; |
|
200 | 209 |
LOG(L_ERR, "ERROR: init_epoll: epoll_create: %s [%d]\n", |
201 | 210 |
strerror(errno), errno); |
202 | 211 |
return -1; |
... | ... |
@@ -222,8 +231,10 @@ static void destroy_epoll(io_wait_h* h) |
222 | 231 |
* returns -1 on error, 0 on success */ |
223 | 232 |
static int init_kqueue(io_wait_h* h) |
224 | 233 |
{ |
234 |
+again: |
|
225 | 235 |
h->kq_fd=kqueue(); |
226 | 236 |
if (h->kq_fd==-1){ |
237 |
+ if (errno==EINTR) goto again; |
|
227 | 238 |
LOG(L_ERR, "ERROR: init_kqueue: kqueue: %s [%d]\n", |
228 | 239 |
strerror(errno), errno); |
229 | 240 |
return -1; |
... | ... |
@@ -244,6 +255,35 @@ static void destroy_kqueue(io_wait_h* h) |
244 | 255 |
|
245 | 256 |
|
246 | 257 |
|
258 |
+#ifdef HAVE_DEVPOLL |
|
259 |
+/* /dev/poll specific init |
|
260 |
+ * returns -1 on error, 0 on success */ |
|
261 |
+static int init_devpoll(io_wait_h* h) |
|
262 |
+{ |
|
263 |
+again: |
|
264 |
+ h->dpoll_fd=open("/dev/poll", O_RDWR); |
|
265 |
+ if (h->dpoll_fd==-1){ |
|
266 |
+ if (errno==EINTR) goto again; |
|
267 |
+ LOG(L_ERR, "ERROR: init_/dev/poll: open: %s [%d]\n", |
|
268 |
+ strerror(errno), errno); |
|
269 |
+ return -1; |
|
270 |
+ } |
|
271 |
+ return 0; |
|
272 |
+} |
|
273 |
+ |
|
274 |
+ |
|
275 |
+ |
|
276 |
+static void destroy_devpoll(io_wait_h* h) |
|
277 |
+{ |
|
278 |
+ if (h->dpoll_fd!=-1){ |
|
279 |
+ close(h->dpoll_fd); |
|
280 |
+ h->dpoll_fd=-1; |
|
281 |
+ } |
|
282 |
+} |
|
283 |
+#endif |
|
284 |
+ |
|
285 |
+ |
|
286 |
+ |
|
247 | 287 |
#ifdef HAVE_SELECT |
248 | 288 |
static int init_select(io_wait_h* h) |
249 | 289 |
{ |
... | ... |
@@ -346,7 +386,19 @@ char* check_poll_method(enum poll_types poll_method) |
346 | 386 |
ret="kqueue not supported on OpenBSD < 2.9 (?)"; |
347 | 387 |
#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */ |
348 | 388 |
#endif |
349 |
- break; |
|
389 |
+ break; |
|
390 |
+ case POLL_DEVPOLL: |
|
391 |
+#ifndef HAVE_DEVPOLL |
|
392 |
+ ret="/dev/poll not supported, try re-compiling with" |
|
393 |
+ " -DHAVE_DEVPOLL"; |
|
394 |
+#else |
|
395 |
+ /* only in Solaris >= 7.0 (?) */ |
|
396 |
+ #ifdef __OS_solaris |
|
397 |
+ if (os_ver<0x0507) /* ver < 5.7 */ |
|
398 |
+ ret="/dev/poll not supported on Solaris < 7.0 (SunOS 5.7)"; |
|
399 |
+ #endif |
|
400 |
+#endif |
|
401 |
+ break; |
|
350 | 402 |
|
351 | 403 |
default: |
352 | 404 |
ret="unknown not supported method"; |
... | ... |
@@ -380,6 +432,14 @@ enum poll_types choose_poll_method() |
380 | 432 |
#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */ |
381 | 433 |
poll_method=POLL_KQUEUE; |
382 | 434 |
#endif |
435 |
+#ifdef HAVE_DEVPOLL |
|
436 |
+ #ifdef __OS_solaris |
|
437 |
+ if (poll_method==0) |
|
438 |
+ /* only in Solaris >= 7.0 (?) */ |
|
439 |
+ if (os_ver>=0x0507) /* if ver >=SunOS 5.7 */ |
|
440 |
+ poll_method=POLL_DEVPOLL; |
|
441 |
+ #endif |
|
442 |
+#endif |
|
383 | 443 |
#ifdef HAVE_SIGIO_RT |
384 | 444 |
if (poll_method==0) |
385 | 445 |
if (os_ver>=0x020200) /* if ver >= 2.2.0 */ |
... | ... |
@@ -435,6 +495,9 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method) |
435 | 495 |
#endif |
436 | 496 |
#ifdef HAVE_KQUEUE |
437 | 497 |
h->kq_fd=-1; |
498 |
+#endif |
|
499 |
+#ifdef HAVE_DEVPOLL |
|
500 |
+ h->dpoll_fd=-1; |
|
438 | 501 |
#endif |
439 | 502 |
poll_err=check_poll_method(poll_method); |
440 | 503 |
|
... | ... |
@@ -456,7 +519,7 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method) |
456 | 519 |
|
457 | 520 |
h->poll_method=poll_method; |
458 | 521 |
|
459 |
- /* common stuff, evrybody has fd_hash */ |
|
522 |
+ /* common stuff, everybody has fd_hash */ |
|
460 | 523 |
h->fd_hash=local_malloc(sizeof(*(h->fd_hash))*h->max_fd_no); |
461 | 524 |
if (h->fd_hash==0){ |
462 | 525 |
LOG(L_CRIT, "ERROR: init_io_wait: could not alloc" |
... | ... |
@@ -473,6 +536,9 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method) |
473 | 536 |
#endif |
474 | 537 |
#ifdef HAVE_SIGIO_RT |
475 | 538 |
case POLL_SIGIO_RT: |
539 |
+#endif |
|
540 |
+#ifdef HAVE_DEVPOLL |
|
541 |
+ case POLL_DEVPOLL: |
|
476 | 542 |
#endif |
477 | 543 |
h->fd_array=local_malloc(sizeof(*(h->fd_array))*h->max_fd_no); |
478 | 544 |
if (h->fd_array==0){ |
... | ... |
@@ -488,6 +554,12 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method) |
488 | 554 |
goto error; |
489 | 555 |
} |
490 | 556 |
#endif |
557 |
+#ifdef HAVE_DEVPOLL |
|
558 |
+ if ((poll_method==POLL_DEVPOLL) && (init_devpoll(h)<0)){ |
|
559 |
+ LOG(L_CRIT, "ERROR: init_io_wait: /dev/poll init failed\n"); |
|
560 |
+ goto error; |
|
561 |
+ } |
|
562 |
+#endif |
|
491 | 563 |
#ifdef HAVE_SELECT |
492 | 564 |
if ((poll_method==POLL_SELECT) && (init_select(h)<0)){ |
493 | 565 |
LOG(L_CRIT, "ERROR: init_io_wait: select init failed\n"); |
... | ... |
@@ -582,6 +654,11 @@ void destroy_io_wait(io_wait_h* h) |
582 | 654 |
case POLL_SIGIO_RT: |
583 | 655 |
destroy_sigio(h); |
584 | 656 |
break; |
657 |
+#endif |
|
658 |
+#ifdef HAVE_DEVPOLL |
|
659 |
+ case POLL_DEVPOLL: |
|
660 |
+ destroy_devpoll(h); |
|
661 |
+ break; |
|
585 | 662 |
#endif |
586 | 663 |
default: /*do nothing*/ |
587 | 664 |
; |
... | ... |
@@ -47,6 +47,7 @@ |
47 | 47 |
* -------- |
48 | 48 |
* 2005-06-13 created by andrei |
49 | 49 |
* 2005-06-26 added kqueue (andrei) |
50 |
+ * 2005-07-01 added /dev/poll (andrei) |
|
50 | 51 |
*/ |
51 | 52 |
|
52 | 53 |
|
... | ... |
@@ -70,6 +71,9 @@ |
70 | 71 |
#include <sys/event.h> |
71 | 72 |
#include <sys/time.h> |
72 | 73 |
#endif |
74 |
+#ifdef HAVE_DEVPOLL |
|
75 |
+#include <sys/devpoll.h> |
|
76 |
+#endif |
|
73 | 77 |
#ifdef HAVE_SELECT |
74 | 78 |
/* needed on openbsd for select*/ |
75 | 79 |
#include <sys/time.h> |
... | ... |
@@ -140,6 +144,9 @@ struct io_wait_handler{ |
140 | 144 |
size_t kq_changes_size; /* size of the changes array */ |
141 | 145 |
int kq_fd; |
142 | 146 |
#endif |
147 |
+#ifdef HAVE_DEVPOLL |
|
148 |
+ int dpoll_fd; |
|
149 |
+#endif |
|
143 | 150 |
#ifdef HAVE_SELECT |
144 | 151 |
fd_set master_set; |
145 | 152 |
int max_fd_select; /* maximum select used fd */ |
... | ... |
@@ -293,6 +300,9 @@ inline static int io_watch_add( io_wait_h* h, |
293 | 300 |
#ifdef HAVE_SIGIO_RT |
294 | 301 |
static char buf[65536]; |
295 | 302 |
#endif |
303 |
+#ifdef HAVE_DEVPOLL |
|
304 |
+ struct pollfd pfd; |
|
305 |
+#endif |
|
296 | 306 |
|
297 | 307 |
if (fd==-1){ |
298 | 308 |
LOG(L_CRIT, "BUG: io_watch_add: fd is -1!\n"); |
... | ... |
@@ -390,6 +400,21 @@ again2: |
390 | 400 |
goto error; |
391 | 401 |
break; |
392 | 402 |
#endif |
403 |
+#ifdef HAVE_DEVPOLL |
|
404 |
+ case POLL_DEVPOLL: |
|
405 |
+ pfd.fd=fd; |
|
406 |
+ pfd.events=POLLIN; |
|
407 |
+ pfd.revents=0; |
|
408 |
+again_devpoll: |
|
409 |
+ if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){ |
|
410 |
+ if (errno==EAGAIN) goto again_devpoll; |
|
411 |
+ LOG(L_ERR, "ERROR: io_watch_add: /dev/poll write failed:" |
|
412 |
+ "%s [%d]\n", strerror(errno), errno); |
|
413 |
+ goto error; |
|
414 |
+ } |
|
415 |
+ break; |
|
416 |
+#endif |
|
417 |
+ |
|
393 | 418 |
default: |
394 | 419 |
LOG(L_CRIT, "BUG: io_watch_add: no support for poll method " |
395 | 420 |
" %s (%d)\n", poll_method_str[h->poll_method], |
... | ... |
@@ -441,6 +466,9 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags) |
441 | 466 |
int n; |
442 | 467 |
struct epoll_event ep_event; |
443 | 468 |
#endif |
469 |
+#ifdef HAVE_DEVPOLL |
|
470 |
+ struct pollfd pfd; |
|
471 |
+#endif |
|
444 | 472 |
|
445 | 473 |
if ((fd<0) || (fd>=h->max_fd_no)){ |
446 | 474 |
LOG(L_CRIT, "BUG: io_watch_del: invalid fd %d, not in [0, %d) \n", |
... | ... |
@@ -509,6 +537,23 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags) |
509 | 537 |
goto error; |
510 | 538 |
} |
511 | 539 |
break; |
540 |
+#endif |
|
541 |
+#ifdef HAVE_DEVPOLL |
|
542 |
+ case POLL_DEVPOLL: |
|
543 |
+ /* for /dev/poll the closed fds _must_ be removed |
|
544 |
+ (they are not removed automatically on close()) */ |
|
545 |
+ pfd.fd=fd; |
|
546 |
+ pfd.events=POLLREMOVE; |
|
547 |
+ pfd.revents=0; |
|
548 |
+again_devpoll: |
|
549 |
+ if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){ |
|
550 |
+ if (errno==EINTR) goto again_devpoll; |
|
551 |
+ LOG(L_ERR, "ERROR: io_watch_del: removing fd from " |
|
552 |
+ "/dev/poll failed: %s [%d]\n", |
|
553 |
+ strerror(errno), errno); |
|
554 |
+ goto error; |
|
555 |
+ } |
|
556 |
+ break; |
|
512 | 557 |
#endif |
513 | 558 |
default: |
514 | 559 |
LOG(L_CRIT, "BUG: io_watch_del: no support for poll method " |
... | ... |
@@ -530,7 +575,7 @@ error: |
530 | 575 |
* params: h - io_wait handle |
531 | 576 |
* t - timeout in s |
532 | 577 |
* repeat - if !=0 handle_io will be called until it returns <=0 |
533 |
- * returns: 0 on success, -1 on err |
|
578 |
+ * returns: number of IO events handled on success (can be 0), -1 on error |
|
534 | 579 |
*/ |
535 | 580 |
inline static int io_wait_loop_poll(io_wait_h* h, int t, int repeat) |
536 | 581 |
{ |
... | ... |
@@ -778,6 +823,43 @@ error: |
778 | 823 |
|
779 | 824 |
|
780 | 825 |
|
826 |
+#ifdef HAVE_DEVPOLL |
|
827 |
+inline static int io_wait_loop_devpoll(io_wait_h* h, int t, int repeat) |
|
828 |
+{ |
|
829 |
+ int n, r; |
|
830 |
+ int ret; |
|
831 |
+ struct dvpoll dpoll; |
|
832 |
+ |
|
833 |
+ dpoll.dp_timeout=t*1000; |
|
834 |
+ dpoll.dp_nfds=h->fd_no; |
|
835 |
+ dpoll.dp_fds=h->fd_array; |
|
836 |
+again: |
|
837 |
+ ret=n=ioctl(h->dpoll_fd, DP_POLL, &dpoll); |
|
838 |
+ if (n==-1){ |
|
839 |
+ if (errno==EINTR) goto again; /* signal, ignore it */ |
|
840 |
+ else{ |
|
841 |
+ LOG(L_ERR, "ERROR:io_wait_loop_devpoll: ioctl: %s [%d]\n", |
|
842 |
+ strerror(errno), errno); |
|
843 |
+ goto error; |
|
844 |
+ } |
|
845 |
+ } |
|
846 |
+ for (r=0; r< n; r++){ |
|
847 |
+ if (h->fd_array[r].revents & (POLLNVAL|POLLERR)){ |
|
848 |
+ LOG(L_ERR, "ERROR: io_wait_loop_devpoll: pollinval returned" |
|
849 |
+ " for fd %d, revents=%x\n", |
|
850 |
+ h->fd_array[r].fd, h->fd_array[r].revents); |
|
851 |
+ } |
|
852 |
+ /* POLLIN|POLLHUP just go through */ |
|
853 |
+ while((handle_io(get_fd_map(h, h->fd_array[r].fd), r) > 0) && |
|
854 |
+ repeat); |
|
855 |
+ } |
|
856 |
+error: |
|
857 |
+ return ret; |
|
858 |
+} |
|
859 |
+#endif |
|
860 |
+ |
|
861 |
+ |
|
862 |
+ |
|
781 | 863 |
/* init */ |
782 | 864 |
|
783 | 865 |
|
... | ... |
@@ -55,6 +55,7 @@ |
55 | 55 |
* 2005-06-07 new tcp optimized code, supports epoll (LT), sigio + real time |
56 | 56 |
* signals, poll & select (andrei) |
57 | 57 |
* 2005-06-26 *bsd kqueue support (andrei) |
58 |
+ * 2005-07-04 solaris /dev/poll support (andrei) |
|
58 | 59 |
*/ |
59 | 60 |
|
60 | 61 |
|
... | ... |
@@ -1515,6 +1516,14 @@ void tcp_main_loop() |
1515 | 1516 |
tcpconn_timeout(); |
1516 | 1517 |
} |
1517 | 1518 |
break; |
1519 |
+#endif |
|
1520 |
+#ifdef HAVE_DEVPOLL |
|
1521 |
+ case POLL_DEVPOLL: |
|
1522 |
+ while(1){ |
|
1523 |
+ io_wait_loop_devpoll(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0); |
|
1524 |
+ tcpconn_timeout(); |
|
1525 |
+ } |
|
1526 |
+ break; |
|
1518 | 1527 |
#endif |
1519 | 1528 |
default: |
1520 | 1529 |
LOG(L_CRIT, "BUG: tcp_main_loop: no support for poll method " |
... | ... |
@@ -1530,7 +1539,6 @@ error: |
1530 | 1539 |
|
1531 | 1540 |
|
1532 | 1541 |
|
1533 |
- |
|
1534 | 1542 |
/* cleanup before exit */ |
1535 | 1543 |
void destroy_tcp() |
1536 | 1544 |
{ |