IP to Geo

IP to Geo Commit Details

Date:2016-02-04 20:39:50 (4 years 8 months ago)
Author:Grégory Soutadé
Branch:master
Commit:58b0439d9d3724136a0106e0f89251200fb14b3c
Parents: 73732adbef88a8b2c50f514a02247e629f8037fd
Message:Use poll instead of select

Changes:
Msrc/server.c (15 diffs)

File differences

src/server.c
1
12
23
34
5
46
57
68
......
1113
1214
1315
16
1417
1518
1619
......
1922
2023
2124
25
26
27
2228
2329
2430
2531
2632
2733
28
29
3034
3135
3236
......
3943
4044
4145
46
4247
4348
4449
......
5358
5459
5560
56
57
5861
5962
6063
......
8083
8184
8285
86
8387
8488
8589
......
134138
135139
136140
137
141
142
143
144
145
146
138147
139148
140149
......
158167
159168
160169
170
161171
162172
163173
......
177187
178188
179189
190
191
180192
181193
182194
183
184
185
195
196
197
186198
187199
188200
189
190
191201
192202
193203
......
199209
200210
201211
202
203
204
205
212
213
214
206215
207216
208217
......
215224
216225
217226
218
227
228
229
230
219231
220232
221
222
223
233
234
224235
225
236
237
238
226239
227240
228241
229242
230243
231244
245
232246
233247
234248
......
238252
239253
240254
241
255
256
242257
243258
244259
245
260
261
262
246263
247264
248
265
266
249267
268
269
270
271
272
273
274
275
276
277
250278
251279
252280
253
281
254282
255
283
256284
257285
258286
......
273301
274302
275303
276
304
305
306
277307
278308
279309
......
294324
295325
296326
327
297328
298329
299
330
300331
301332
302333
......
330361
331362
332363
333
364
334365
335366
336367
#define _GNU_SOURCE 1 // for POLLRDHUP && syncfs
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#ifdef USE_SECCOMP
#include <seccomp.h>
#include "ip_to_geo.h"
#include "protocol.h"
#define WAIT_TIME 100
#define MAX_WAIT_TIME 500
typedef struct {
int socket;
time_t timeout;
int nb_remaining_requests;
} socket_ctx_t;
// TODO : sandbox
typedef struct thread_ctx_s{
struct thread_ctx_s* prev;
struct thread_ctx_s* next;
int stop;
int quiet;
pthread_mutex_t mutex;
struct pollfd * pollfds;
} thread_ctx_t;
static pthread_mutex_t s_fastmutex = PTHREAD_MUTEX_INITIALIZER;
shutdown(s_server_socket, SHUT_RDWR);
}
// TODO signal capture
static int check_request(request_t* req)
{
if (req->magic != REQ_MAGIC)
{
request_t req;
const uint8_t* geo;
int sent=0;
int ret = read(socket, &req, sizeof(req));
// Socket closed
}
}
write(socket, &req, sizeof(req));
for (sent=0; sent < sizeof(req); sent += ret)
{
ret = write(socket, &((uint8_t*)&req)[sent], sizeof(req)-sent);
if (ret < 0)
return -1;
}
return 0;
}
}
free(thread_ctx->sockets);
free(thread_ctx->pollfds);
if (thread_ctx->next)
thread_ctx->next->prev = thread_ctx->prev;
close(socket->socket);
}
#define POLL_ERR_MASK (POLLRDHUP|POLLERR|POLLHUP|POLLNVAL)
static void* thread_loop(void* param)
{
thread_ctx_t* ctx = (thread_ctx_t*)param;
int i, ret, nfds, nb_cur_sockets, nb_available_sockets;
fd_set read_set, exc_set;
struct timeval timeout;
int i, ret, nfds, nb_cur_sockets, nb_available_sockets, poll_idx;
struct timeval time1, time2, time_res;
int wait_time = WAIT_TIME;
while (!ctx->stop)
{
FD_ZERO(&read_set);
FD_ZERO(&exc_set);
nfds = 0;
pthread_mutex_lock(&ctx->mutex);
{
if (ctx->sockets[i].timeout > 0)
{
FD_SET(ctx->sockets[i].socket, &read_set);
FD_SET(ctx->sockets[i].socket, &exc_set);
if (ctx->sockets[i].socket > nfds)
nfds = ctx->sockets[i].socket;
ctx->pollfds[nfds].fd = ctx->sockets[i].socket;
ctx->pollfds[nfds].events = POLLIN|POLL_ERR_MASK;
nfds++;
}
}
if (!nb_available_sockets)
break;
usleep(100);
if (wait_time < MAX_WAIT_TIME)
wait_time += WAIT_TIME;
usleep(wait_time);
continue;
}
timeout.tv_sec = ctx->max_timeout;
timeout.tv_usec = 0;
else
wait_time = WAIT_TIME;
ret = select(nfds+1, &read_set, NULL, &exc_set, &timeout);
gettimeofday(&time1, NULL);
ret = poll(ctx->pollfds, nfds, ctx->max_timeout);
gettimeofday(&time2, NULL);
// Timeout, remove all current sockets
if (ret == 0)
{
if (ctx->quiet < 0)
syslog(LOG_DEBUG, "Timeout");
for(i=0; i<nb_cur_sockets; i++)
{
if (ctx->sockets[i].timeout > 0)
else if (ret < 0)
{
if (!s_stop && !ctx->stop)
syslog(LOG_WARNING, "select has errors (%m)\n");
syslog(LOG_WARNING, "poll has errors (%m)\n");
break;
}
else
{
for(i=0; i<nb_cur_sockets; i++)
timersub(&time2, &time1, &time_res);
poll_idx = -1;
for(i=0; i<ctx->nb_cur_sockets; i++)
{
if (ctx->sockets[i].timeout < 0) continue;
if (FD_ISSET(ctx->sockets[i].socket, &exc_set))
poll_idx++;
if (ctx->pollfds[poll_idx].fd != ctx->sockets[i].socket)
{
if (ctx->quiet < 0)
syslog(LOG_ERR, "Socket not found but present in poll fds");
continue;
}
// Error
if (ctx->pollfds[poll_idx].revents & POLL_ERR_MASK)
{
if (ctx->quiet < 0)
syslog(LOG_ERR, "Error with socket %d", ctx->sockets[i].socket);
close_socket(&ctx->sockets[i]);
}
// Someone is speaking
else if (FD_ISSET(ctx->sockets[i].socket, &read_set))
else if (ctx->pollfds[poll_idx].revents & POLLIN)
{
ctx->sockets[i].timeout = ctx->max_timeout;
ctx->sockets[i].timeout = ctx->max_timeout*1000;
ret = handle_request(ctx, ctx->sockets[i].socket);
if (ret == 1)
{
}
else
{
ctx->sockets[i].timeout -= timeout.tv_sec*1000000 + timeout.tv_usec;
ctx->sockets[i].timeout -= (time_res.tv_sec*1000000 + time_res.tv_usec);
if (ctx->sockets[i].timeout <= 0)
close_socket(&ctx->sockets[i]);
}
}
}
syslog(LOG_DEBUG, "Create a new thread %p", thread_ctx);
thread_ctx->sockets = malloc(sizeof(*thread_ctx->sockets)*params->sockets_per_thread_arg);
thread_ctx->pollfds = malloc(sizeof(*thread_ctx->pollfds)*params->sockets_per_thread_arg);
thread_ctx->nb_cur_sockets = 0;
thread_ctx->nb_available_sockets = params->sockets_per_thread_arg;
thread_ctx->max_timeout = params->sockets_timeout_arg*1000000;
thread_ctx->max_timeout = params->sockets_timeout_arg*1000;
thread_ctx->stop = 0;
thread_ctx->quiet = params->quiet_flag;
if (params->verbose_flag)
pthread_mutex_unlock(&s_fastmutex);
thread_ctx->sockets[thread_ctx->nb_cur_sockets].socket = socket;
thread_ctx->sockets[thread_ctx->nb_cur_sockets].timeout = thread_ctx->max_timeout;
thread_ctx->sockets[thread_ctx->nb_cur_sockets].timeout = thread_ctx->max_timeout*1000; // ms -> us
thread_ctx->sockets[thread_ctx->nb_cur_sockets].nb_remaining_requests = params->client_max_requests_arg;
pthread_mutex_lock(&thread_ctx->mutex);

Archive Download the corresponding diff file

Branches

Tags