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 1 : PATHPOOL path_pool = {
13 : .count = 0,
14 : .paths = NULL
15 : };
16 :
17 316 : while(!abort_signaled){
18 : //clear listen fds
19 315 : FD_ZERO(&readfds);
20 315 : maxfd = -1;
21 :
22 : //add listen fds
23 2205 : for(i = 0; i < listeners.count; i++){
24 1890 : if(listeners.conns[i].fd >= 0){
25 1890 : FD_SET(listeners.conns[i].fd, &readfds);
26 1890 : if(listeners.conns[i].fd > maxfd){
27 1890 : maxfd = listeners.conns[i].fd;
28 : }
29 : }
30 : }
31 :
32 : //add client fds
33 800 : for(i = 0; i < clients.count; i++){
34 485 : if(clients.conns[i].fd >= 0){
35 377 : FD_SET(clients.conns[i].fd, &readfds);
36 377 : if(clients.conns[i].fd > maxfd){
37 0 : maxfd = clients.conns[i].fd;
38 : }
39 : }
40 : }
41 :
42 : //reset timeout
43 315 : select_timeout.tv_sec = CMAIL_SELECT_TIMEOUT;
44 315 : select_timeout.tv_usec = 0;
45 :
46 : //select over fds
47 315 : status = select(maxfd + 1, &readfds, NULL, NULL, &select_timeout);
48 :
49 315 : if(status < 0){
50 1 : logprintf(log, LOG_ERROR, "Error in select: %s\n", strerror(errno));
51 1 : break;
52 : }
53 : else{
54 314 : logprintf(log, LOG_DEBUG, "Data on %d sockets\n", status);
55 : }
56 :
57 : //check client fds
58 797 : for(i = 0; i < clients.count; i++){
59 483 : if(clients.conns[i].fd >= 0){
60 377 : if(FD_ISSET(clients.conns[i].fd, &readfds)){
61 : //handle data
62 : //FIXME handle return value
63 293 : client_process(log, &(clients.conns[i]), database, &path_pool);
64 : }
65 84 : else if(client_timeout(log, &(clients.conns[i]))){
66 0 : logprintf(log, LOG_WARNING, "Client timed out, disconnecting\n");
67 0 : client_send(log, &(clients.conns[i]), "500 Timed out\r\n");
68 0 : client_close(&(clients.conns[i]));
69 : }
70 : }
71 : else{
72 : //periodically release unused memory
73 106 : client_memtimeout(log, &(clients.conns[i]));
74 : }
75 : }
76 :
77 : //check listen fds
78 2198 : for(i = 0; i < listeners.count; i++){
79 1884 : if(listeners.conns[i].fd >= 0 && FD_ISSET(listeners.conns[i].fd, &readfds)){
80 : //handle new client
81 : //FIXME handle return value
82 15 : client_accept(log, database, &(listeners.conns[i]), &clients);
83 : }
84 : }
85 : }
86 :
87 : //close connected clients
88 3 : for(i = 0; i < clients.count; i++){
89 2 : if(clients.conns[i].fd >= 0){
90 0 : client_close(&(clients.conns[i]));
91 : }
92 :
93 : //free allocated data
94 2 : client_free(log, &(clients.conns[i]));
95 : }
96 :
97 1 : connpool_free(&clients);
98 1 : pathpool_free(&path_pool);
99 :
100 1 : return 0;
101 : }
|