src/Network/Reactor.cc
changeset 380 d193dd1d8a7e
child 384 6d387796b139
equal deleted inserted replaced
379:2a8e780844d2 380:d193dd1d8a7e
       
     1 
       
     2 #include "Reactor.hh"
       
     3 
       
     4 
       
     5 NetworkReactor::NetworkReactor (void) :
       
     6     sockets()
       
     7 {
       
     8 
       
     9 }
       
    10 
       
    11 void NetworkReactor::poll (timeval *timeout) {
       
    12     // start counting the maximum fd from -1, so that select is given nfds=0 if our list is empty
       
    13     int fd_max = 0;
       
    14 
       
    15     // zero our fdsets
       
    16     fd_set read, write;
       
    17     FD_ZERO(&read);
       
    18     FD_ZERO(&write);
       
    19 
       
    20     // inspect our sockets
       
    21     for (std::list<NetworkSocket*>::iterator it = sockets.begin(); it != sockets.end(); it++) {
       
    22         NetworkSocket *socket = *it;
       
    23     
       
    24         // ask socket what events it wants
       
    25         NetworkPollMask mask = socket->get_poll();
       
    26 
       
    27         // set read/write
       
    28         if (mask) {
       
    29             // socket file descriptor...
       
    30             int fd = socket->get_socket();
       
    31 
       
    32             // ignore invalid FDs
       
    33             if (fd < 0)
       
    34                 continue;
       
    35             
       
    36             // update fd_max?
       
    37             if (fd > fd_max)
       
    38                 fd_max = fd;
       
    39             
       
    40             // read...
       
    41             if (mask & POLL_READ)
       
    42                 FD_SET(socket->get_socket(), &read);
       
    43             
       
    44             // write...
       
    45             if (mask & POLL_WRITE)
       
    46                 FD_SET(socket->get_socket(), &write);
       
    47         }
       
    48     }
       
    49 
       
    50     // run select
       
    51     int ret;
       
    52     
       
    53     // we never care about except
       
    54     // pass NULL fdsets if they are empty
       
    55     if ((ret = select(
       
    56             fd_max + 1, 
       
    57             fd_max ? &read : NULL, 
       
    58             fd_max ? &write : NULL, 
       
    59             NULL, 
       
    60             timeout
       
    61     )) < 0)
       
    62         throw NetworkReactorError("select");
       
    63     
       
    64     // ignore if we just timed out
       
    65     if (ret == 0)
       
    66         return;
       
    67 
       
    68     // notify up to <ret> socket-events
       
    69     for (std::list<NetworkSocket*>::iterator it = sockets.begin(); it != sockets.end() && ret > 0; it++) {
       
    70         NetworkSocket *socket = *it;
       
    71 
       
    72         // socket file descriptor...
       
    73         int fd = socket->get_socket();
       
    74             
       
    75         // ignore invalid FDs
       
    76         if (fd < 0)
       
    77             continue;
       
    78         
       
    79         // mask of events detected
       
    80         NetworkPollMask mask = 0;
       
    81         
       
    82         // detect read
       
    83         if (FD_ISSET(fd, &read)) {
       
    84             mask |= POLL_READ;
       
    85             ret--;
       
    86         }
       
    87 
       
    88         // detect write
       
    89         if (FD_ISSET(fd, &write)) {
       
    90             mask |= POLL_WRITE;
       
    91             ret--;
       
    92         }
       
    93         
       
    94         // notify?
       
    95         if (mask)
       
    96             socket->notify(mask);
       
    97     }
       
    98 }
       
    99 
       
   100 // the global reactor
       
   101 static NetworkReactor g_reactor;
       
   102 NetworkReactor *NetworkReactor::current = &g_reactor;
       
   103