Branch data Line data Source code
1 : : /**
2 : : * \file
3 : : *
4 : : * \author Georg Hopp
5 : : *
6 : : * \copyright
7 : : * Copyright © 2012 Georg Hopp
8 : : *
9 : : * This program is free software: you can redistribute it and/or modify
10 : : * it under the terms of the GNU General Public License as published by
11 : : * the Free Software Foundation, either version 3 of the License, or
12 : : * (at your option) any later version.
13 : : *
14 : : * This program is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : : * GNU General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU General Public License
20 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : : */
22 : :
23 : : #include "server.h"
24 : : #include "logger.h"
25 : :
26 : : #include "utils/signalHandling.h"
27 : :
28 : : int serverPoll(Server);
29 : : int serverHandleAccept(Server, unsigned int);
30 : : ssize_t serverRead(Server, unsigned int);
31 : : ssize_t serverWrite(Server, unsigned int);
32 : : void serverCloseConn(Server, unsigned int);
33 : :
34 : :
35 : : void
36 : 1 : serverRun(Server this)
37 : : {
38 : 1 : int events = 0;
39 : :
40 : 1 : loggerLog(this->logger, LOGGER_INFO, "service started");
41 : :
42 : 235 : while (!doShutdown) //! until error or signal
43 : : {
44 : : unsigned int i;
45 : :
46 : 233 : if (0 <= events) {
47 : : /*
48 : : * TODO check why sometimes events is less than 0
49 : : * There is still a misshandling here.
50 : : */
51 : 233 : events = serverPoll(this);
52 : : }
53 : :
54 : : /**
55 : : * handle accept
56 : : */
57 : 233 : if (0 != ((this->fds)[0].revents & POLLIN)) {
58 : 1 : while (0 < serverHandleAccept(this, 0)) {}
59 : 1 : events--;
60 : : }
61 : :
62 : 233 : if (events == 0) {
63 : 1 : continue;
64 : : }
65 : :
66 : : /**
67 : : * handle accept SSL
68 : : */
69 : 232 : if (0 != ((this->fds)[1].revents & POLLIN)) {
70 : 0 : while (0 < serverHandleAccept(this, 1)) {}
71 : 0 : events--;
72 : : }
73 : :
74 : 232 : if (events == 0) {
75 : 0 : continue;
76 : : }
77 : :
78 : 463 : for (i=2; i < this->nfds; i++) {
79 : : /**
80 : : * handle reads
81 : : */
82 : 232 : if (0 != ((this->fds)[i].revents & POLLIN)) {
83 : 231 : ssize_t processed = serverRead(this, i);
84 : :
85 : 231 : if (0 > processed) {
86 : 0 : events--;
87 : :
88 : 0 : switch (processed) {
89 : : case -2: // close me...
90 : 0 : serverCloseConn(this, i);
91 : :
92 : : case -1: // poll me again
93 : 0 : break;
94 : : }
95 : : }
96 : :
97 : 231 : if (0 < processed) {
98 : 1 : (this->fds)[i].events |= POLLOUT;
99 : : }
100 : : }
101 : :
102 : 232 : if (events == 0) {
103 : 0 : break;
104 : : }
105 : :
106 : : /**
107 : : * handle writes
108 : : */
109 : 232 : if (0 != ((this->fds)[i].revents & POLLOUT)) {
110 : 1 : ssize_t remaining = serverWrite(this, i);
111 : :
112 : 1 : if (0 >= remaining) {
113 : : /*
114 : : * 0 means queue was empty...try again next
115 : : * time...no need to poll again.
116 : : * Anyway, most likely we need to read again
117 : : * so lets finish this event for now.
118 : : */
119 : 1 : events--;
120 : :
121 : 1 : switch (remaining) {
122 : : case 0: // nothing more to write stop polling
123 : 1 : (this->fds)[i].events &= ~POLLOUT;
124 : 1 : break;
125 : :
126 : : case -2: // close me...
127 : 0 : serverCloseConn(this, i);
128 : :
129 : : case -1: // poll me again
130 : 0 : break;
131 : : }
132 : : }
133 : : }
134 : :
135 : 232 : if (events == 0) {
136 : 1 : break; // no more events to handle
137 : : }
138 : : }
139 : : }
140 : 1 : }
141 : :
142 : : // vim: set ts=4 sw=4:
|