Changeset 3

Show
Ignore:
Timestamp:
19/04/06 00:48:49 (3 years ago)
Author:
smoku
Message:

epoll support patch applied

Location:
trunk
Files:
6 added
23 modified

Legend:

Unmodified
Added
Removed
  • trunk/c2s/c2s.c

    r2 r3  
    4141 
    4242        case event_READ: 
    43             log_debug(ZONE, "reading from %d", sess->fd); 
     43            log_debug(ZONE, "reading from %d", sess->fd->fd); 
    4444 
    4545            /* check rate limits */ 
     
    5050                    if(!sess->rate_log) { 
    5151                        if(s->state >= state_STREAM && sess->jid != NULL) 
    52                             log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] is being byte rate limited", sess->fd, sess->jid); 
     52                            log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] is being byte rate limited", sess->fd->fd, sess->jid); 
    5353                        else 
    54                             log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] is being byte rate limited", sess->fd, sess->ip, sess->port); 
     54                            log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] is being byte rate limited", sess->fd->fd, sess->ip, sess->port); 
    5555 
    5656                        sess->rate_log = 1; 
    5757                    } 
    5858 
    59                     log_debug(ZONE, "%d is throttled, delaying read", sess->fd); 
     59                    log_debug(ZONE, "%d is throttled, delaying read", sess->fd->fd); 
    6060 
    6161                    buf->len = 0; 
     
    7070 
    7171            /* do the read */ 
    72             len = recv(sess->fd, buf->data, buf->len, 0); 
     72            len = recv(sess->fd->fd, buf->data, buf->len, 0); 
    7373 
    7474            if(len < 0) { 
     
    7979 
    8080                if(s->state >= state_STREAM && sess->jid != NULL) 
    81                     log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] read error: %s (%d)", sess->fd, jid_full(sess->jid), strerror(errno), errno); 
     81                    log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] read error: %s (%d)", sess->fd->fd, jid_full(sess->jid), strerror(errno), errno); 
    8282                else 
    83                     log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] read error: %s (%d)", sess->fd, sess->ip, sess->port, strerror(errno), errno); 
     83                    log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] read error: %s (%d)", sess->fd->fd, sess->ip, sess->port, strerror(errno), errno); 
    8484 
    8585                sx_kill(s); 
     
    102102 
    103103        case event_WRITE: 
    104             log_debug(ZONE, "writing to %d", sess->fd); 
    105  
    106             len = send(sess->fd, buf->data, buf->len, 0); 
     104            log_debug(ZONE, "writing to %d", sess->fd->fd); 
     105 
     106            len = send(sess->fd->fd, buf->data, buf->len, 0); 
    107107            if(len >= 0) { 
    108108                log_debug(ZONE, "%d bytes written", len); 
     
    114114             
    115115            if(s->state >= state_OPEN && sess->jid != NULL) 
    116                 log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] write error: %s (%d)", sess->fd, jid_full(sess->jid), strerror(errno), errno); 
     116                log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] write error: %s (%d)", sess->fd->fd, jid_full(sess->jid), strerror(errno), errno); 
    117117            else 
    118                 log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s. port=%d] write error: %s (%d)", sess->fd, sess->ip, sess->port, strerror(errno), errno); 
     118                log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s. port=%d] write error: %s (%d)", sess->fd->fd, sess->ip, sess->port, strerror(errno), errno); 
    119119         
    120120            sx_kill(s); 
     
    125125            sxe = (sx_error_t *) data; 
    126126            if(sess->jid != NULL) 
    127                 log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] error: %s (%s)", sess->fd, jid_full(sess->jid), sxe->generic, sxe->specific); 
     127                log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s] error: %s (%s)", sess->fd->fd, jid_full(sess->jid), sxe->generic, sxe->specific); 
    128128            else 
    129                 log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] error: %s (%s)", sess->fd, sess->ip, sess->port, sxe->generic, sxe->specific); 
     129                log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] error: %s (%s)", sess->fd->fd, sess->ip, sess->port, sxe->generic, sxe->specific); 
    130130 
    131131            break; 
     
    337337        case event_CLOSED: 
    338338            mio_close(sess->c2s->mio, sess->fd); 
    339  
    340             break; 
     339            return -1; 
    341340    } 
    342341 
     
    344343} 
    345344 
    346 static int _c2s_client_accept_check(c2s_t c2s, int fd, char *ip) { 
     345static int _c2s_client_accept_check(c2s_t c2s, mio_fd_t fd, char *ip) { 
    347346    rate_t rt; 
    348347 
    349348    if(access_check(c2s->access, ip) == 0) { 
    350         log_write(c2s->log, LOG_NOTICE, "[%d] [%s] access denied by configuration", fd, ip); 
     349        log_write(c2s->log, LOG_NOTICE, "[%d] [%s] access denied by configuration", fd->fd, ip); 
    351350        return 1; 
    352351    } 
     
    361360 
    362361        if(rate_check(rt) == 0) { 
    363             log_write(c2s->log, LOG_NOTICE, "[%d] [%s] is being rate limited", fd, ip); 
     362            log_write(c2s->log, LOG_NOTICE, "[%d] [%s] is being rate limited", fd->fd, ip); 
    364363            return 1; 
    365364        } 
     
    371370} 
    372371 
    373 static int _c2s_client_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) { 
     372static int _c2s_client_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) { 
    374373    sess_t sess = (sess_t) arg; 
    375374    c2s_t c2s = (c2s_t) arg; 
     
    379378    switch(a) { 
    380379        case action_READ: 
    381             log_debug(ZONE, "read action on fd %d", fd); 
     380            log_debug(ZONE, "read action on fd %d", fd->fd); 
    382381 
    383382            /* they did something */ 
    384383            sess->last_activity = time(NULL); 
    385384 
    386             ioctl(fd, FIONREAD, &nbytes); 
     385            ioctl(fd->fd, FIONREAD, &nbytes); 
    387386            if(nbytes == 0) { 
    388387                sx_kill(sess->s); 
     
    393392 
    394393        case action_WRITE: 
    395             log_debug(ZONE, "write action on fd %d", fd); 
     394            log_debug(ZONE, "write action on fd %d", fd->fd); 
    396395 
    397396            return sx_can_write(sess->s); 
    398397 
    399398        case action_CLOSE: 
    400             log_debug(ZONE, "close action on fd %d", fd); 
    401  
    402             log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] disconnect", sess->fd, sess->ip, sess->port); 
     399            log_debug(ZONE, "close action on fd %d", fd->fd); 
     400 
     401            log_write(sess->c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] disconnect", sess->fd->fd, sess->ip, sess->port); 
    403402 
    404403            /* tell the sm to close their session */ 
     
    415414 
    416415        case action_ACCEPT: 
    417             log_debug(ZONE, "accept action on fd %d", fd); 
    418  
    419             getpeername(fd, (struct sockaddr *) &sa, &namelen); 
     416            log_debug(ZONE, "accept action on fd %d", fd->fd); 
     417 
     418            getpeername(fd->fd, (struct sockaddr *) &sa, &namelen); 
    420419            port = j_inet_getport(&sa); 
    421420 
    422             log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] connect", fd, (char *) data, port); 
     421            log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] connect", fd->fd, (char *) data, port); 
    423422 
    424423            if(_c2s_client_accept_check(c2s, fd, (char *) data) != 0) 
     
    438437            sess->last_activity = time(NULL); 
    439438 
    440             sess->s = sx_new(c2s->sx_env, fd, _c2s_client_sx_callback, (void *) sess); 
     439            sess->s = sx_new(c2s->sx_env, fd->fd, _c2s_client_sx_callback, (void *) sess); 
    441440            mio_app(m, fd, _c2s_client_mio_callback, (void *) sess); 
    442441 
     
    445444 
    446445            /* find out which port this is */ 
    447             getsockname(fd, (struct sockaddr *) &sa, &namelen); 
     446            getsockname(fd->fd, (struct sockaddr *) &sa, &namelen); 
    448447            port = j_inet_getport(&sa); 
    449448 
    450449            /* remember it */ 
    451             sprintf(sess->skey, "%d", fd); 
     450            sprintf(sess->skey, "%d", fd->fd); 
    452451            xhash_put(c2s->sessions, sess->skey, (void *) sess); 
    453452 
     
    543542 
    544543        case event_READ: 
    545             log_debug(ZONE, "reading from %d", c2s->fd); 
     544            log_debug(ZONE, "reading from %d", c2s->fd->fd); 
    546545 
    547546            /* do the read */ 
    548             len = recv(c2s->fd, buf->data, buf->len, 0); 
     547            len = recv(c2s->fd->fd, buf->data, buf->len, 0); 
    549548 
    550549            if(len < 0) { 
     
    554553                } 
    555554 
    556                 log_write(c2s->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", c2s->fd, strerror(errno), errno); 
     555                log_write(c2s->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", c2s->fd->fd, strerror(errno), errno); 
    557556 
    558557                sx_kill(s); 
     
    575574 
    576575        case event_WRITE: 
    577             log_debug(ZONE, "writing to %d", c2s->fd); 
    578  
    579             len = send(c2s->fd, buf->data, buf->len, 0); 
     576            log_debug(ZONE, "writing to %d", c2s->fd->fd); 
     577 
     578            len = send(c2s->fd->fd, buf->data, buf->len, 0); 
    580579            if(len >= 0) { 
    581580                log_debug(ZONE, "%d bytes written", len); 
     
    586585                return 0; 
    587586 
    588             log_write(c2s->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", c2s->fd, strerror(errno), errno); 
     587            log_write(c2s->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", c2s->fd->fd, strerror(errno), errno); 
    589588         
    590589            sx_kill(s); 
     
    690689                    if(c2s->local_port != 0) { 
    691690                        c2s->server_fd = mio_listen(c2s->mio, c2s->local_port, c2s->local_ip, _c2s_client_mio_callback, (void *) c2s); 
    692                         if(c2s->server_fd < 0) 
     691                        if(c2s->server_fd == NULL) 
    693692                            log_write(c2s->log, LOG_ERR, "[%s, port=%d] failed to listen", c2s->local_ip, c2s->local_port); 
    694693                        else 
    695694                            log_write(c2s->log, LOG_NOTICE, "[%s, port=%d] listening for connections", c2s->local_ip, c2s->local_port); 
    696695                    } else 
    697                         c2s->server_fd = -1; 
     696                        c2s->server_fd = NULL; 
    698697             
    699698#ifdef HAVE_SSL 
    700699                    if(c2s->local_ssl_port != 0 && c2s->local_pemfile != NULL) { 
    701700                        c2s->server_ssl_fd = mio_listen(c2s->mio, c2s->local_ssl_port, c2s->local_ip, _c2s_client_mio_callback, (void *) c2s); 
    702                         if(c2s->server_ssl_fd < 0) 
     701                        if(c2s->server_ssl_fd == NULL) 
    703702                            log_write(c2s->log, LOG_ERR, "[%s, port=%d] failed to listen", c2s->local_ip, c2s->local_ssl_port); 
    704703                        else 
    705704                            log_write(c2s->log, LOG_NOTICE, "[%s, port=%d] listening for SSL connections", c2s->local_ip, c2s->local_ssl_port); 
    706705                    } else 
    707                         c2s->server_ssl_fd = -1; 
     706                        c2s->server_ssl_fd = NULL; 
    708707#endif 
    709708                } 
    710709 
    711710#ifdef HAVE_SSL 
    712                 if(c2s->server_fd < 0 && c2s->server_ssl_fd < 0) { 
     711                if(c2s->server_fd == NULL && c2s->server_ssl_fd == NULL) { 
    713712                    log_write(c2s->log, LOG_ERR, "both normal and SSL ports are disabled, nothing to do!"); 
    714713#else 
    715                 if(c2s->server_fd < 0) { 
     714                if(c2s->server_fd == NULL) { 
    716715                    log_write(c2s->log, LOG_ERR, "server port is disabled, nothing to do!"); 
    717716#endif 
     
    10261025        case event_CLOSED: 
    10271026            mio_close(c2s->mio, c2s->fd); 
    1028             break; 
     1027            return -1; 
    10291028    } 
    10301029 
     
    10321031} 
    10331032 
    1034 int c2s_router_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) { 
     1033int c2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) { 
    10351034    c2s_t c2s = (c2s_t) arg; 
    10361035    int nbytes; 
     
    10381037    switch(a) { 
    10391038        case action_READ: 
    1040             log_debug(ZONE, "read action on fd %d", fd); 
    1041  
    1042             ioctl(fd, FIONREAD, &nbytes); 
     1039            log_debug(ZONE, "read action on fd %d", fd->fd); 
     1040 
     1041            ioctl(fd->fd, FIONREAD, &nbytes); 
    10431042            if(nbytes == 0) { 
    10441043                sx_kill(c2s->router); 
     
    10491048 
    10501049        case action_WRITE: 
    1051             log_debug(ZONE, "write action on fd %d", fd); 
     1050            log_debug(ZONE, "write action on fd %d", fd->fd); 
    10521051            return sx_can_write(c2s->router); 
    10531052 
    10541053        case action_CLOSE: 
    1055             log_debug(ZONE, "close action on fd %d", fd); 
     1054            log_debug(ZONE, "close action on fd %d", fd->fd); 
    10561055            log_write(c2s->log, LOG_NOTICE, "connection to router closed"); 
    10571056 
  • trunk/c2s/c2s.h

    r2 r3  
    4444    c2s_t               c2s; 
    4545 
    46     int                 fd; 
     46    mio_fd_t            fd; 
    4747 
    4848    char                skey[10]; 
     
    106106    /** router's conn */ 
    107107    sx_t                router; 
    108     int                 fd; 
     108    mio_fd_t            fd; 
    109109 
    110110    /** listening sockets */ 
    111     int                 server_fd; 
     111    mio_fd_t            server_fd; 
    112112#ifdef HAVE_SSL 
    113     int                 server_ssl_fd; 
     113    mio_fd_t            server_ssl_fd; 
    114114#endif 
    115115 
     
    213213extern sig_atomic_t c2s_lost_router; 
    214214 
    215 int             c2s_router_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg); 
     215int             c2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg); 
    216216int             c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg); 
    217217 
  • trunk/c2s/main.c

    r2 r3  
    221221 
    222222    c2s->fd = mio_connect(c2s->mio, c2s->router_port, c2s->router_ip, c2s_router_mio_callback, (void *) c2s); 
    223     if(c2s->fd < 0) { 
     223    if(c2s->fd == NULL) { 
    224224        if(errno == ECONNREFUSED) 
    225225            c2s_lost_router = 1; 
     
    228228    } 
    229229 
    230     c2s->router = sx_new(c2s->sx_env, c2s->fd, c2s_router_sx_callback, (void *) c2s); 
     230    c2s->router = sx_new(c2s->sx_env, c2s->fd->fd, c2s_router_sx_callback, (void *) c2s); 
    231231    sx_client_init(c2s->router, 0, NULL, NULL, NULL, "1.0"); 
    232232 
     
    383383 
    384384            if(c2s->io_check_idle > 0 && now > sess->last_activity + c2s->io_check_idle) { 
    385                 log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd, sess->ip, sess->port); 
     385                log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd->fd, sess->ip, sess->port); 
    386386 
    387387                sx_error(sess->s, stream_err_HOST_GONE, "connection timed out"); 
     
    392392 
    393393            if(c2s->io_check_keepalive > 0 && now > sess->last_activity + c2s->io_check_keepalive && sess->s->state >= state_STREAM) { 
    394                 log_debug(ZONE, "sending keepalive for %d", sess->fd); 
     394                log_debug(ZONE, "sending keepalive for %d", sess->fd->fd); 
    395395 
    396396                sx_raw_write(sess->s, " ", 1); 
  • trunk/configure.in

    r2 r3  
    611611dnl 
    612612AC_ARG_ENABLE(mio, AC_HELP_STRING([--enable-mio=BACKEND], [use BACKEND to drive MIO]),  
    613               mio_check=$enableval, mio_check='poll select') 
     613              mio_check=$enableval, mio_check='epoll poll select') 
    614614 
    615615mio_backend='' 
    616616for backend in $mio_check ; do 
    617     if test "x-$mio_backend" = "x-" ; then 
    618         case x-$backend in 
    619  
    620             x-poll) 
    621                 AC_CHECK_HEADERS(poll.h) 
    622                 if test "x-$ac_cv_header_poll_h" = "x-yes" ; then 
    623                     AC_CHECK_FUNCS(poll,[ 
    624                         mio_backend='poll' 
    625                         AC_DEFINE(MIO_POLL,1,[Define to 1 if you want to use 'poll' for non-blocking I/O.])]) 
    626                 fi 
    627                 ;; 
    628  
    629             x-select) 
    630                 AC_CHECK_HEADERS(sys/select.h) 
    631                 if test "x-$ac_cv_header_sys_select_h" = "x-yes" ; then 
    632                     AC_CHECK_FUNCS(select, have_select=yes) 
    633                 fi 
    634  
    635                 if test "x-$have_select" != "x-yes" -a "x-$ac_cv_header_winsock2_h" = "x-yes" ; then 
    636                     AC_MSG_CHECKING([for select in ws2_32]) 
    637                     AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]], 
    638                                                     [[select(0,0,0,0,0)]])], 
    639                                    [AC_MSG_RESULT(yes) 
    640                                     have_select=yes], 
    641                                    AC_MSG_RESULT(no)) 
    642                 fi 
    643  
    644                 if test "x-$have_select" = "x-yes" ; then 
    645                     mio_backend='select' 
    646                     AC_DEFINE(MIO_SELECT,1,[Define to 1 if you want to use 'select' for non-blocking I/O.]) 
    647                 fi 
    648                 ;; 
    649         esac 
    650     fi 
     617    case x-$backend in 
     618 
     619        x-epoll) 
     620            AC_CHECK_HEADERS(sys/epoll.h) 
     621            if test "x-$ac_cv_header_sys_epoll_h" = "x-yes" ; then 
     622                AC_CHECK_FUNCS(epoll_create,[ 
     623                    mio_backend='epoll' 
     624                    AC_DEFINE(MIO_EPOLL,1,[Define to 1 if you want to use 'epoll' for non-blocking I/O.])]) 
     625            fi 
     626            ;; 
     627 
     628        x-poll) 
     629            AC_CHECK_HEADERS(poll.h) 
     630            if test "x-$ac_cv_header_poll_h" = "x-yes" ; then 
     631                AC_CHECK_FUNCS(poll,[ 
     632                    mio_backend='poll' 
     633                    AC_DEFINE(MIO_POLL,1,[Define to 1 if you want to use 'poll' for non-blocking I/O.])]) 
     634            fi 
     635            ;; 
     636 
     637        x-select) 
     638            AC_CHECK_HEADERS(sys/select.h) 
     639            if test "x-$ac_cv_header_sys_select_h" = "x-yes" ; then 
     640                AC_CHECK_FUNCS(select, have_select=yes) 
     641            fi 
     642 
     643            if test "x-$have_select" != "x-yes" -a "x-$ac_cv_header_winsock2_h" = "x-yes" ; then 
     644                AC_MSG_CHECKING([for select in ws2_32]) 
     645                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]], 
     646                                                [[select(0,0,0,0,0)]])], 
     647                               [AC_MSG_RESULT(yes) 
     648                                have_select=yes], 
     649                               AC_MSG_RESULT(no)) 
     650            fi 
     651 
     652            if test "x-$have_select" = "x-yes" ; then 
     653                mio_backend='select' 
     654                AC_DEFINE(MIO_SELECT,1,[Define to 1 if you want to use 'select' for non-blocking I/O.]) 
     655            fi 
     656            ;; 
     657    esac 
    651658done 
    652659 
  • trunk/mio/Makefile.am

    r2 r3  
    33noinst_HEADERS = mio.h mio_poll.h mio_select.h 
    44 
    5 libmio_la_SOURCES = mio.c 
     5libmio_la_SOURCES = mio.c mio_epoll.c mio_poll.c mio_select.c 
    66libmio_la_LIBADD = @LDFLAGS@ 
  • trunk/mio/mio.c

    r2 r3  
    22 * jabberd - Jabber Open Source Server 
    33 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 
    4  *                    Ryan Eatmon, Robert Norris 
     4 *                    Ryan Eatmon, Robert Norris, Christof Meerwald 
    55 * 
    66 * This program is free software; you can redistribute it and/or modify 
     
    3030#include "mio.h" 
    3131 
    32 #include "util/inaddr.h" 
     32 
     33mio_t mio_epoll_new(int maxfd); 
     34mio_t mio_poll_new(int maxfd); 
     35mio_t mio_select_new(int maxfd); 
     36 
     37mio_t mio_new(int maxfd) 
     38{ 
     39  mio_t m = NULL; 
     40 
     41#ifdef MIO_EPOLL 
     42  m = mio_epoll_new(maxfd); 
     43  if (m != NULL) return m; 
     44#endif 
     45 
     46#ifdef MIO_SELECT 
     47  m = mio_select_new(maxfd); 
     48  if (m != NULL) return m; 
     49#endif 
    3350 
    3451#ifdef MIO_POLL 
    35 #include "mio_poll.h" 
    36 #endif 
    37 #ifdef MIO_SELECT 
    38 #include "mio_select.h" 
     52  m = mio_poll_new(maxfd); 
     53  if (m != NULL) return m; 
    3954#endif 
    4055 
    41 /** our internal wrapper around a fd */ 
    42 typedef enum {  
    43     type_CLOSED = 0x00,  
    44     type_NORMAL = 0x01,  
    45     type_LISTEN = 0x02,  
    46     type_CONNECT = 0x10,  
    47     type_CONNECT_READ = 0x11, 
    48     type_CONNECT_WRITE = 0x12 
    49 } mio_type_t; 
    50 struct mio_fd_st 
    51 { 
    52     mio_type_t type; 
    53     /* app event handler and data */ 
    54     mio_handler_t app; 
    55     void *arg; 
    56 }; 
    57  
    58 /** now define our master data type */ 
    59 struct mio_st 
    60 { 
    61     struct mio_fd_st *fds; 
    62     int maxfd; 
    63     int highfd; 
    64     MIO_VARS 
    65 }; 
    66  
    67 /* lazy factor */ 
    68 #define FD(m,f) m->fds[f] 
    69 #define ACT(m,f,a,d) (*(FD(m,f).app))(m,a,f,d,FD(m,f).arg) 
    70  
    71 /* temp debug outputter */ 
    72 #define ZONE __LINE__ 
    73 #ifndef MIO_DEBUG 
    74 #define MIO_DEBUG 0 
    75 #endif 
    76 #define mio_debug if(MIO_DEBUG) _mio_debug 
    77 void _mio_debug(int line, const char *msgfmt, ...) 
    78 { 
    79     va_list ap; 
    80     va_start(ap,msgfmt); 
    81     fprintf(stderr,"mio.c#%d: ",line); 
    82     vfprintf(stderr,msgfmt,ap); 
    83     fprintf(stderr,"\n"); 
     56  return m; 
    8457} 
    85  
    86 MIO_FUNCS 
    87  
    88 /** internal close function */ 
    89 void mio_close(mio_t m, int fd) 
    90 { 
    91     mio_debug(ZONE,"actually closing fd #%d",fd); 
    92  
    93     /* take out of poll sets */ 
    94     MIO_REMOVE_FD(m, fd); 
    95  
    96     /* let the app know, it must process any waiting write data it has and free it's arg */ 
    97     ACT(m, fd, action_CLOSE, NULL); 
    98  
    99     /* close the socket, and reset all memory */ 
    100     close(fd); 
    101     memset(&FD(m,fd), 0, sizeof(struct mio_fd_st)); 
    102 } 
    103  
    104 /** internally accept an incoming connection from a listen sock */ 
    105 void _mio_accept(mio_t m, int fd) 
    106 { 
    107     struct sockaddr_storage serv_addr; 
    108     socklen_t addrlen = (socklen_t) sizeof(serv_addr); 
    109     int newfd, dupfd; 
    110     char ip[INET6_ADDRSTRLEN]; 
    111  
    112     mio_debug(ZONE, "accepting on fd #%d", fd); 
    113