summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/opentracker.c b/opentracker.c
index 2eaf988..e5efff5 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -109,20 +109,9 @@ static void *server_mainloop(void *args) {
109 109
110 (void)args; 110 (void)args;
111 111
112 /* Initialize our "thread local storage" */ 112 if (workstruct_init(&ws) == -1)
113 memset(&ws, 0, sizeof(ws));
114 stats_counters_register(&ws);
115 ws.inbuf = malloc(G_INBUF_SIZE);
116 ws.outbuf = malloc(G_OUTBUF_SIZE);
117#ifdef _DEBUG_HTTPERROR
118 ws.debugbuf = malloc(G_DEBUGBUF_SIZE);
119#endif
120
121 if (!ws.inbuf || !ws.outbuf)
122 panic("Initializing worker failed"); 113 panic("Initializing worker failed");
123 114
124 random_bytes(ws.rand48_state, sizeof(ws.rand48_state));
125
126 while (g_opentracker_running) { 115 while (g_opentracker_running) {
127 ot_event ready[OT_EVENT_BATCH]; 116 ot_event ready[OT_EVENT_BATCH];
128 int64_t sock; 117 int64_t sock;
@@ -173,13 +162,7 @@ static void *server_mainloop(void *args) {
173 162
174 /* This work struct is about to go out of scope, so hand its tally over 163 /* This work struct is about to go out of scope, so hand its tally over
175 before anything can read it there */ 164 before anything can read it there */
176 stats_counters_retire(&ws); 165 workstruct_deinit(&ws);
177
178 free(ws.inbuf);
179 free(ws.outbuf);
180#ifdef _DEBUG_HTTPERROR
181 free(ws.debugbuf);
182#endif
183 return 0; 166 return 0;
184} 167}
185 168
@@ -188,7 +171,7 @@ static void *server_mainloop(void *args) {
188 member asked for it before binding, the first one included, so whether 171 member asked for it before binding, the first one included, so whether
189 this entry will have workers has to be known here. */ 172 this entry will have workers has to be known here. */
190static socket_sharing listen_sharing_for(const ot_listen *entry) { 173static socket_sharing listen_sharing_for(const ot_listen *entry) {
191 if (entry->proto == FLAG_UDP && entry->workers > 1 && socket_can_balance()) 174 if (entry->proto != FLAG_MCA && entry->workers > 1 && socket_can_balance())
192 return SOCKET_BALANCED; 175 return SOCKET_BALANCED;
193 return entry->shared ? SOCKET_SHARED : SOCKET_EXCLUSIVE; 176 return entry->shared ? SOCKET_SHARED : SOCKET_EXCLUSIVE;
194} 177}
@@ -244,10 +227,41 @@ static void listen_bind_all(void) {
244 listen_bind_one(entries + i); 227 listen_bind_one(entries + i);
245} 228}
246 229
247/* The socket the event loop was using becomes the first worker's. Where the 230/* The socket the event loop was using is passed to the first worker.
248 kernel spreads datagrams, every further worker binds one of its own, so 231 If start up tests show that the kernel can spread connections over
249 none of them share a receive queue. 232 a group bound to one address, every worker binds one of its own.
250 All others read from the first */ 233 If not, all workers call accept on the first. */
234static void listen_start_tcp_workers(void) {
235 size_t count, i;
236 ot_listen *entries = config_listen_entries(&count);
237
238 for (i = 0; i < count; ++i) {
239 ot_listen *entry = entries + i;
240 int balance = listen_sharing_for(entry) == SOCKET_BALANCED;
241 int worker;
242
243 if (entry->proto != FLAG_TCP || entry->workers <= 0)
244 continue;
245
246 event_del((int)entry->sock);
247 tcp_worker_install(entry->sock);
248
249 for (worker = 1; worker < entry->workers; ++worker) {
250 int64_t sock = entry->sock;
251
252 if (balance) {
253 sock = socket_tcp_listen(entry->ip, entry->port, SOCKET_BALANCED);
254 if (sock == -1) {
255 fprintf(stderr, "Warning: could not bind another socket for tcp worker %d: %s. Sharing the first instead.\n", worker,
256 strerror(errno));
257 sock = entry->sock;
258 }
259 }
260 tcp_worker_install(sock);
261 }
262 }
263}
264
251static void listen_start_udp_workers(void) { 265static void listen_start_udp_workers(void) {
252 size_t count, i; 266 size_t count, i;
253 ot_listen *entries = config_listen_entries(&count); 267 ot_listen *entries = config_listen_entries(&count);
@@ -408,9 +422,11 @@ int main(int argc, char **argv) {
408 422
409 install_signal_handlers(); 423 install_signal_handlers();
410 424
425 listen_start_tcp_workers();
411 listen_start_udp_workers(); 426 listen_start_udp_workers();
412 427
413 server_mainloop(0); 428 server_mainloop(0);
429 tcp_workers_deinit();
414 udp_workers_deinit(); 430 udp_workers_deinit();
415 431
416 /* No thread is serving any more, so the teardown can run where a debugger 432 /* No thread is serving any more, so the teardown can run where a debugger