diff options
Diffstat (limited to 'ot_tcp.c')
| -rw-r--r-- | ot_tcp.c | 27 |
1 files changed, 26 insertions, 1 deletions
| @@ -5,6 +5,10 @@ | |||
| 5 | 5 | ||
| 6 | /* System */ | 6 | /* System */ |
| 7 | #include <errno.h> | 7 | #include <errno.h> |
| 8 | #include <pthread.h> | ||
| 9 | #include <stdatomic.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | #include <stdlib.h> | ||
| 8 | #include <string.h> | 12 | #include <string.h> |
| 9 | #include <unistd.h> | 13 | #include <unistd.h> |
| 10 | 14 | ||
| @@ -16,6 +20,7 @@ | |||
| 16 | #include "ot_http.h" | 20 | #include "ot_http.h" |
| 17 | #include "ot_mutex.h" | 21 | #include "ot_mutex.h" |
| 18 | #include "ot_socket.h" | 22 | #include "ot_socket.h" |
| 23 | #include "ot_worker.h" | ||
| 19 | #include "ot_stats.h" | 24 | #include "ot_stats.h" |
| 20 | #include "ot_tcp.h" | 25 | #include "ot_tcp.h" |
| 21 | #include "trackerlogic.h" | 26 | #include "trackerlogic.h" |
| @@ -149,9 +154,29 @@ void tcp_accept(const int64_t serversocket, struct ot_workstruct *ws) { | |||
| 149 | if (fdstate_generation((int)sock) != generation) | 154 | if (fdstate_generation((int)sock) != generation) |
| 150 | continue; | 155 | continue; |
| 151 | 156 | ||
| 152 | if (http_adopt(sock, &cookie) == -1) | 157 | /* Handling it may already have given it a heap home and handed it to |
| 158 | another thread, and then it is no longer this frame's to touch */ | ||
| 159 | if (fdstate_cookie((int)sock) != &cookie) | ||
| 160 | fdstate_release((int)sock); | ||
| 161 | else if (!http_adopt(sock)) | ||
| 153 | http_close(sock); | 162 | http_close(sock); |
| 154 | else | 163 | else |
| 155 | fdstate_release((int)sock); | 164 | fdstate_release((int)sock); |
| 156 | } | 165 | } |
| 157 | } | 166 | } |
| 167 | |||
| 168 | /* A worker blocks in accept and nowhere else: the connection it is handed is | ||
| 169 | non blocking, so a client that stops talking is given to the event loop | ||
| 170 | rather than keeping this thread. */ | ||
| 171 | static void tcp_run(struct ot_worker *me) { | ||
| 172 | while (g_opentracker_running) | ||
| 173 | tcp_accept(me->sock, &me->ws); | ||
| 174 | } | ||
| 175 | |||
| 176 | void tcp_worker_install(int64_t sock) { | ||
| 177 | socket_set_blocking((int)sock, 1); | ||
| 178 | socket_defer_accept((int)sock); | ||
| 179 | |||
| 180 | if (worker_start(tcp_run, sock) == -1) | ||
| 181 | fprintf(stderr, "Warning: could not install a tcp worker, this socket stays with the workers already running.\n"); | ||
| 182 | } | ||
