author | Tero Marttila <terom@fixme.fi> |
Fri, 16 Jan 2009 22:03:49 +0200 | |
changeset 400 | d64bf28c4340 |
parent 384 | 6d387796b139 |
permissions | -rw-r--r-- |
380 | 1 |
|
2 |
#include "Reactor.hh" |
|
3 |
||
4 |
NetworkReactor::NetworkReactor (void) : |
|
5 |
sockets() |
|
6 |
{ |
|
7 |
||
8 |
} |
|
9 |
||
10 |
void NetworkReactor::poll (timeval *timeout) { |
|
384 | 11 |
int ret; |
12 |
||
400
d64bf28c4340
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
Tero Marttila <terom@fixme.fi>
parents:
384
diff
changeset
|
13 |
// start counting the maximum fd from 0, select will be given nfds=1 if empty |
380 | 14 |
int fd_max = 0; |
15 |
||
16 |
// zero our fdsets |
|
17 |
fd_set read, write; |
|
18 |
FD_ZERO(&read); |
|
19 |
FD_ZERO(&write); |
|
20 |
||
21 |
// inspect our sockets |
|
22 |
for (std::list<NetworkSocket*>::iterator it = sockets.begin(); it != sockets.end(); it++) { |
|
23 |
NetworkSocket *socket = *it; |
|
24 |
||
25 |
// ask socket what events it wants |
|
26 |
NetworkPollMask mask = socket->get_poll(); |
|
27 |
||
400
d64bf28c4340
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
Tero Marttila <terom@fixme.fi>
parents:
384
diff
changeset
|
28 |
// ignore if nothing |
380 | 29 |
if (mask) { |
30 |
// socket file descriptor... |
|
31 |
int fd = socket->get_socket(); |
|
32 |
||
33 |
// ignore invalid FDs |
|
34 |
if (fd < 0) |
|
35 |
continue; |
|
36 |
||
37 |
// update fd_max? |
|
38 |
if (fd > fd_max) |
|
39 |
fd_max = fd; |
|
40 |
||
41 |
// read... |
|
42 |
if (mask & POLL_READ) |
|
400
d64bf28c4340
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
Tero Marttila <terom@fixme.fi>
parents:
384
diff
changeset
|
43 |
FD_SET(fd, &read); |
380 | 44 |
|
45 |
// write... |
|
46 |
if (mask & POLL_WRITE) |
|
400
d64bf28c4340
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
Tero Marttila <terom@fixme.fi>
parents:
384
diff
changeset
|
47 |
FD_SET(fd, &write); |
380 | 48 |
} |
49 |
} |
|
50 |
||
384 | 51 |
// loop select() on EINTR |
52 |
do { |
|
53 |
// we never care about except, and pass NULL fdsets if they are empty |
|
54 |
ret = select( |
|
380 | 55 |
fd_max + 1, |
56 |
fd_max ? &read : NULL, |
|
57 |
fd_max ? &write : NULL, |
|
58 |
NULL, |
|
59 |
timeout |
|
384 | 60 |
); |
61 |
} while (ret < 0 && errno == EINTR); |
|
62 |
||
63 |
// error? |
|
64 |
if (ret < 0) |
|
380 | 65 |
throw NetworkReactorError("select"); |
66 |
||
67 |
// ignore if we just timed out |
|
68 |
if (ret == 0) |
|
69 |
return; |
|
70 |
||
71 |
// notify up to <ret> socket-events |
|
72 |
for (std::list<NetworkSocket*>::iterator it = sockets.begin(); it != sockets.end() && ret > 0; it++) { |
|
73 |
NetworkSocket *socket = *it; |
|
74 |
||
75 |
// socket file descriptor... |
|
76 |
int fd = socket->get_socket(); |
|
77 |
||
78 |
// ignore invalid FDs |
|
79 |
if (fd < 0) |
|
80 |
continue; |
|
81 |
||
82 |
// mask of events detected |
|
83 |
NetworkPollMask mask = 0; |
|
84 |
||
85 |
// detect read |
|
86 |
if (FD_ISSET(fd, &read)) { |
|
87 |
mask |= POLL_READ; |
|
88 |
ret--; |
|
89 |
} |
|
90 |
||
91 |
// detect write |
|
92 |
if (FD_ISSET(fd, &write)) { |
|
93 |
mask |= POLL_WRITE; |
|
94 |
ret--; |
|
95 |
} |
|
96 |
||
97 |
// notify? |
|
98 |
if (mask) |
|
99 |
socket->notify(mask); |
|
100 |
} |
|
101 |
} |
|
102 |
||
103 |
// the global reactor |
|
104 |
static NetworkReactor g_reactor; |
|
105 |
NetworkReactor *NetworkReactor::current = &g_reactor; |
|
106 |