diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-24 20:21:20 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-24 20:21:20 +0000 |
commit | 5603840c1b45a0cd46e3d5cf074d30e65f5bb91a (patch) | |
tree | bdefdf6eaa88e901285b62cf3326fe3dc3b3766f /src/mesh | |
parent | 4640985528ba9d810c6cd2396d759210a9e49de4 (diff) | |
download | gnunet-5603840c1b45a0cd46e3d5cf074d30e65f5bb91a.tar.gz gnunet-5603840c1b45a0cd46e3d5cf074d30e65f5bb91a.zip |
-fixing disconnect shutdown sequence
Diffstat (limited to 'src/mesh')
-rw-r--r-- | src/mesh/mesh_api.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c index 0638f9f85..b76bbf361 100644 --- a/src/mesh/mesh_api.c +++ b/src/mesh/mesh_api.c | |||
@@ -380,48 +380,21 @@ destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner) | |||
380 | struct GNUNET_MESH_Handle *h; | 380 | struct GNUNET_MESH_Handle *h; |
381 | struct GNUNET_PeerIdentity pi; | 381 | struct GNUNET_PeerIdentity pi; |
382 | struct GNUNET_MESH_TransmitHandle *th; | 382 | struct GNUNET_MESH_TransmitHandle *th; |
383 | struct GNUNET_MESH_TransmitHandle *aux; | 383 | struct GNUNET_MESH_TransmitHandle *next; |
384 | unsigned int i; | 384 | unsigned int i; |
385 | 385 | ||
386 | if (NULL == t) | 386 | if (NULL == t) |
387 | { | 387 | { |
388 | GNUNET_break (0); | 388 | GNUNET_break (0); |
389 | return; | 389 | return; |
390 | } | 390 | } |
391 | h = t->mesh; | 391 | h = t->mesh; |
392 | th = h->th_head; | 392 | |
393 | while (NULL != th) | 393 | /* disconnect all peers */ |
394 | { | ||
395 | if (th->tunnel == t) | ||
396 | { | ||
397 | aux = th->next; | ||
398 | GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); | ||
399 | if (NULL == h->th_head && NULL != h->th) | ||
400 | { | ||
401 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
402 | h->th = NULL; | ||
403 | } | ||
404 | if (NULL != th->notify) | ||
405 | th->notify (th->notify_cls, 0, NULL); | ||
406 | if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task) | ||
407 | GNUNET_SCHEDULER_cancel (th->timeout_task); | ||
408 | GNUNET_free (th); | ||
409 | th = aux; | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | th = th->next; | ||
414 | } | ||
415 | } | ||
416 | if (NULL == h->th_head && NULL != h->th) | ||
417 | { | ||
418 | GNUNET_CLIENT_notify_transmit_ready_cancel(h->th); | ||
419 | h->th = NULL; | ||
420 | } | ||
421 | GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t); | 394 | GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t); |
422 | for (i = 0; i < t->npeers; i++) | 395 | for (i = 0; i < t->npeers; i++) |
423 | { | 396 | { |
424 | if (NULL != t->disconnect_handler && t->peers[i]->connected) | 397 | if ( (NULL != t->disconnect_handler) && t->peers[i]->connected) |
425 | { | 398 | { |
426 | GNUNET_PEER_resolve (t->peers[i]->id, &pi); | 399 | GNUNET_PEER_resolve (t->peers[i]->id, &pi); |
427 | t->disconnect_handler (t->cls, &pi); | 400 | t->disconnect_handler (t->cls, &pi); |
@@ -429,10 +402,39 @@ destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner) | |||
429 | GNUNET_PEER_change_rc (t->peers[i]->id, -1); | 402 | GNUNET_PEER_change_rc (t->peers[i]->id, -1); |
430 | GNUNET_free (t->peers[i]); | 403 | GNUNET_free (t->peers[i]); |
431 | } | 404 | } |
405 | |||
406 | /* signal tunnel destruction */ | ||
407 | if ( (NULL != h->cleaner) && (0 != t->owner) && (GNUNET_YES == call_cleaner) ) | ||
408 | h->cleaner (h->cls, t, t->ctx); | ||
409 | |||
410 | /* check that clients did not leave messages behind in the queue */ | ||
411 | for (th = h->th_head; NULL != th; th = next) | ||
412 | { | ||
413 | next = th->next; | ||
414 | if (th->tunnel != t) | ||
415 | continue; | ||
416 | /* we should not really get here, as clients should have | ||
417 | aborted there requests already */ | ||
418 | GNUNET_break (0); | ||
419 | GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); | ||
420 | |||
421 | /* clean up request */ | ||
422 | if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task) | ||
423 | GNUNET_SCHEDULER_cancel (th->timeout_task); | ||
424 | GNUNET_free (th); | ||
425 | } | ||
426 | |||
427 | /* if there are no more pending requests with mesh service, cancel active request */ | ||
428 | /* Note: this should be unnecessary... */ | ||
429 | if ( (NULL == h->th_head) && (NULL != h->th)) | ||
430 | { | ||
431 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
432 | h->th = NULL; | ||
433 | } | ||
434 | |||
435 | |||
432 | if (t->npeers > 0) | 436 | if (t->npeers > 0) |
433 | GNUNET_free (t->peers); | 437 | GNUNET_free (t->peers); |
434 | if (NULL != h->cleaner && 0 != t->owner && GNUNET_YES == call_cleaner) | ||
435 | h->cleaner (h->cls, t, t->ctx); | ||
436 | if (0 != t->owner) | 438 | if (0 != t->owner) |
437 | GNUNET_PEER_change_rc (t->owner, -1); | 439 | GNUNET_PEER_change_rc (t->owner, -1); |
438 | if (0 != t->napps && t->apps) | 440 | if (0 != t->napps && t->apps) |