aboutsummaryrefslogtreecommitdiff
path: root/src/util/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/server.c')
-rw-r--r--src/util/server.c152
1 files changed, 59 insertions, 93 deletions
diff --git a/src/util/server.c b/src/util/server.c
index ff9c8c192..af26d278c 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -123,20 +123,15 @@ struct GNUNET_SERVER_Handle
123 size_t maxbuf; 123 size_t maxbuf;
124 124
125 /** 125 /**
126 * Pipe used to signal shutdown of the server.
127 */
128 struct GNUNET_DISK_PipeHandle *shutpipe;
129
130 /**
131 * Socket used to listen for new connections. Set to 126 * Socket used to listen for new connections. Set to
132 * "-1" by GNUNET_SERVER_destroy to initiate shutdown. 127 * "-1" by GNUNET_SERVER_destroy to initiate shutdown.
133 */ 128 */
134 struct GNUNET_NETWORK_Handle *listen_socket; 129 struct GNUNET_NETWORK_Handle *listen_socket;
135 130
136 /** 131 /**
137 * Set to GNUNET_YES if we are shutting down. 132 * Task scheduled to do the listening.
138 */ 133 */
139 int do_shutdown; 134 GNUNET_SCHEDULER_TaskIdentifier listen_task;
140 135
141 /** 136 /**
142 * Do we ignore messages of types that we do not 137 * Do we ignore messages of types that we do not
@@ -262,42 +257,6 @@ struct GNUNET_SERVER_Client
262 257
263 258
264/** 259/**
265 * Server has been asked to shutdown, free resources.
266 */
267static void
268destroy_server (struct GNUNET_SERVER_Handle *server)
269{
270 struct GNUNET_SERVER_Client *pos;
271 struct HandlerList *hpos;
272 struct NotifyList *npos;
273
274#if DEBUG_SERVER
275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
276#endif
277 GNUNET_assert (server->listen_socket == NULL);
278 if (GNUNET_OK != GNUNET_DISK_pipe_close (server->shutpipe))
279 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "pipe-close");
280 while (server->clients != NULL)
281 {
282 pos = server->clients;
283 server->clients = pos->next;
284 pos->server = NULL;
285 }
286 while (NULL != (hpos = server->handlers))
287 {
288 server->handlers = hpos->next;
289 GNUNET_free (hpos);
290 }
291 while (NULL != (npos = server->disconnect_notify_list))
292 {
293 server->disconnect_notify_list = npos->next;
294 GNUNET_free (npos);
295 }
296 GNUNET_free (server);
297}
298
299
300/**
301 * Scheduler says our listen socket is ready. 260 * Scheduler says our listen socket is ready.
302 * Process it! 261 * Process it!
303 */ 262 */
@@ -309,26 +268,23 @@ process_listen_socket (void *cls,
309 struct GNUNET_CONNECTION_Handle *sock; 268 struct GNUNET_CONNECTION_Handle *sock;
310 struct GNUNET_SERVER_Client *client; 269 struct GNUNET_SERVER_Client *client;
311 struct GNUNET_NETWORK_FDSet *r; 270 struct GNUNET_NETWORK_FDSet *r;
312 const struct GNUNET_DISK_FileHandle *shutpipe;
313 271
314 if ((server->do_shutdown) || 272 server->listen_task = GNUNET_SCHEDULER_NO_TASK;
315 ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)) 273 r = GNUNET_NETWORK_fdset_create ();
274 GNUNET_NETWORK_fdset_set (r, server->listen_socket);
275 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
316 { 276 {
317 /* shutdown was initiated */ 277 server->listen_task = GNUNET_SCHEDULER_add_select (server->sched,
318 GNUNET_assert (server->listen_socket != NULL); 278 GNUNET_SCHEDULER_PRIORITY_HIGH,
319 GNUNET_break (GNUNET_OK == 279 GNUNET_SCHEDULER_NO_TASK,
320 GNUNET_NETWORK_socket_close (server->listen_socket)); 280 GNUNET_TIME_UNIT_FOREVER_REL,
321 server->listen_socket = NULL; 281 r, NULL, &process_listen_socket,
322 if (server->do_shutdown) 282 server);
323 destroy_server (server); 283 GNUNET_NETWORK_fdset_destroy (r);
324 return; 284 return; /* ignore shutdown, someone else will take care of it! */
325 } 285 }
326 shutpipe = GNUNET_DISK_pipe_handle (server->shutpipe,
327 GNUNET_DISK_PIPE_END_READ);
328 GNUNET_assert (GNUNET_NETWORK_fdset_isset 286 GNUNET_assert (GNUNET_NETWORK_fdset_isset
329 (tc->read_ready, server->listen_socket)); 287 (tc->read_ready, server->listen_socket));
330 GNUNET_assert (!GNUNET_NETWORK_fdset_handle_isset
331 (tc->read_ready, shutpipe));
332 sock = 288 sock =
333 GNUNET_CONNECTION_create_from_accept (tc->sched, server->access, 289 GNUNET_CONNECTION_create_from_accept (tc->sched, server->access,
334 server->access_cls, 290 server->access_cls,
@@ -345,14 +301,11 @@ process_listen_socket (void *cls,
345 GNUNET_SERVER_client_drop (client); 301 GNUNET_SERVER_client_drop (client);
346 } 302 }
347 /* listen for more! */ 303 /* listen for more! */
348 r = GNUNET_NETWORK_fdset_create (); 304 server->listen_task = GNUNET_SCHEDULER_add_select (server->sched,
349 GNUNET_NETWORK_fdset_set (r, server->listen_socket); 305 GNUNET_SCHEDULER_PRIORITY_HIGH,
350 GNUNET_NETWORK_fdset_handle_set (r, shutpipe); 306 GNUNET_SCHEDULER_NO_TASK,
351 GNUNET_SCHEDULER_add_select (server->sched, 307 GNUNET_TIME_UNIT_FOREVER_REL,
352 GNUNET_SCHEDULER_PRIORITY_HIGH, 308 r, NULL, &process_listen_socket, server);
353 GNUNET_SCHEDULER_NO_TASK,
354 GNUNET_TIME_UNIT_FOREVER_REL,
355 r, NULL, &process_listen_socket, server);
356 GNUNET_NETWORK_fdset_destroy (r); 309 GNUNET_NETWORK_fdset_destroy (r);
357} 310}
358 311
@@ -454,12 +407,6 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
454 return NULL; 407 return NULL;
455 } 408 }
456 ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); 409 ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
457 if (NULL == (ret->shutpipe = GNUNET_DISK_pipe (GNUNET_NO)))
458 {
459 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lsock));
460 GNUNET_free (ret);
461 return NULL;
462 }
463 ret->sched = sched; 410 ret->sched = sched;
464 ret->maxbuf = maxbuf; 411 ret->maxbuf = maxbuf;
465 ret->idle_timeout = idle_timeout; 412 ret->idle_timeout = idle_timeout;
@@ -471,14 +418,11 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
471 { 418 {
472 r = GNUNET_NETWORK_fdset_create (); 419 r = GNUNET_NETWORK_fdset_create ();
473 GNUNET_NETWORK_fdset_set (r, ret->listen_socket); 420 GNUNET_NETWORK_fdset_set (r, ret->listen_socket);
474 GNUNET_NETWORK_fdset_handle_set (r, 421 ret->listen_task = GNUNET_SCHEDULER_add_select (sched,
475 GNUNET_DISK_pipe_handle (ret->shutpipe, 422 GNUNET_SCHEDULER_PRIORITY_HIGH,
476 GNUNET_DISK_PIPE_END_READ)); 423 GNUNET_SCHEDULER_NO_TASK,
477 GNUNET_SCHEDULER_add_select (sched, 424 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
478 GNUNET_SCHEDULER_PRIORITY_HIGH, 425 &process_listen_socket, ret);
479 GNUNET_SCHEDULER_NO_TASK,
480 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
481 &process_listen_socket, ret);
482 GNUNET_NETWORK_fdset_destroy (r); 426 GNUNET_NETWORK_fdset_destroy (r);
483 } 427 }
484 return ret; 428 return ret;
@@ -491,18 +435,40 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
491void 435void
492GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) 436GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
493{ 437{
494 static char c; 438 struct GNUNET_SERVER_Client *pos;
495 439 struct HandlerList *hpos;
496 GNUNET_assert (s->do_shutdown == GNUNET_NO); 440 struct NotifyList *npos;
497 s->do_shutdown = GNUNET_YES; 441
498 if (s->listen_socket == NULL) 442#if DEBUG_SERVER
499 destroy_server (s); 443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
500 else 444#endif
501 GNUNET_break (1 == 445 if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
502 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 446 {
503 (s->shutpipe, 447 GNUNET_SCHEDULER_cancel (s->sched,
504 GNUNET_DISK_PIPE_END_WRITE), &c, 448 s->listen_task);
505 sizeof (c))); 449 s->listen_task = GNUNET_SCHEDULER_NO_TASK;
450 }
451 GNUNET_break (GNUNET_OK ==
452 GNUNET_NETWORK_socket_close (s->listen_socket));
453 s->listen_socket = NULL;
454 while (s->clients != NULL)
455 {
456 pos = s->clients;
457 s->clients = pos->next;
458 pos->server = NULL;
459 }
460 while (NULL != (hpos = s->handlers))
461 {
462 s->handlers = hpos->next;
463 GNUNET_free (hpos);
464 }
465 while (NULL != (npos = s->disconnect_notify_list))
466 {
467 s->disconnect_notify_list = npos->next;
468 GNUNET_free (npos);
469 }
470 GNUNET_free (s);
471
506} 472}
507 473
508 474