Line data Source code
1 1 : int core_loop(LOGGER log, CONNPOOL listeners, DATABASE* database){
2 : fd_set readfds;
3 : struct timeval select_timeout;
4 : int maxfd;
5 : int status;
6 : unsigned i;
7 1 : CONNPOOL clients = {
8 : .count = 0,
9 : .conns = NULL
10 : };
11 :
12 131 : while(!abort_signaled){
13 : //clear listen fds
14 130 : FD_ZERO(&readfds);
15 130 : maxfd = -1;
16 :
17 : //add listen fds
18 650 : for(i = 0; i < listeners.count; i++){
19 520 : if(listeners.conns[i].fd >= 0){
20 520 : FD_SET(listeners.conns[i].fd, &readfds);
21 520 : if(listeners.conns[i].fd > maxfd){
22 520 : maxfd = listeners.conns[i].fd;
23 : }
24 : }
25 : }
26 :
27 : //add client fds
28 257 : for(i = 0; i < clients.count; i++){
29 127 : if(clients.conns[i].fd >= 0){
30 108 : FD_SET(clients.conns[i].fd, &readfds);
31 108 : if(clients.conns[i].fd > maxfd){
32 99 : maxfd = clients.conns[i].fd;
33 : }
34 : }
35 : }
36 :
37 : //reset timeout
38 130 : select_timeout.tv_sec = CMAIL_SELECT_TIMEOUT;
39 130 : select_timeout.tv_usec = 0;
40 :
41 : //select over fds
42 130 : status = select(maxfd + 1, &readfds, NULL, NULL, &select_timeout);
43 :
44 130 : if(status < 0){
45 1 : logprintf(log, LOG_ERROR, "Core select: %s\n", strerror(errno));
46 1 : break;
47 : }
48 : else{
49 129 : logprintf(log, LOG_DEBUG, "Data on %d sockets\n", status);
50 : }
51 :
52 : //check client fds
53 255 : for(i = 0; i < clients.count; i++){
54 126 : if(clients.conns[i].fd >= 0){
55 108 : if(FD_ISSET(clients.conns[i].fd, &readfds)){
56 : //handle data
57 : //FIXME handle return value
58 107 : client_process(log, &(clients.conns[i]), database);
59 : }
60 1 : else if(client_timeout(log, &(clients.conns[i]))){
61 0 : logprintf(log, LOG_WARNING, "Client timed out, disconnecting\n");
62 0 : client_send(log, &(clients.conns[i]), "-ERR Timed out\r\n");
63 0 : client_close(log, &(clients.conns[i]), database);
64 : }
65 : }
66 : }
67 :
68 : //check listen fds
69 645 : for(i = 0; i < listeners.count; i++){
70 516 : if(listeners.conns[i].fd >= 0 && FD_ISSET(listeners.conns[i].fd, &readfds)){
71 : //handle new client
72 : //FIXME handle return value
73 12 : client_accept(log, &(listeners.conns[i]), &clients);
74 : }
75 : }
76 : }
77 :
78 : //close connected clients
79 2 : for(i = 0; i < clients.count; i++){
80 1 : if(clients.conns[i].fd >= 0){
81 0 : client_close(log, &(clients.conns[i]), database);
82 : }
83 : }
84 :
85 : //TODO free connpool aux_data structures
86 1 : connpool_free(&clients);
87 :
88 1 : return 0;
89 : }
|