From 35131ac6802168472251575e42ae158a8bdf7adc Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 2 Apr 2010 20:58:19 +0000 Subject: [PATCH] fix --- TODO | 2 -- src/fs/fs.h | 7 +++++++ src/fs/fs_download.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 49e647671..22c52e934 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,6 @@ away), in order in which they will likely be done: - utilization can (easily, restart?) go out of control (very large), causing content expiration job to go crazy and delete everything! * FS: [CG] - - EASY BUGS: - + gnunet-download does not terminate when done (stop missing!) - on some systems, keyword search does not find locally published content (need testcase of command-line tools! - also good to cover getopt API!) [could be related to datastore issue above!] diff --git a/src/fs/fs.h b/src/fs/fs.h index 0b3b25955..3a42fee2d 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -1094,6 +1094,13 @@ struct GNUNET_FS_DownloadContext */ enum GNUNET_FS_DownloadOptions options; + /** + * Flag set upon transitive completion (includes child downloads). + * This flag is only set to GNUNET_YES for directories where all + * child-downloads have also completed (and signalled completion). + */ + int has_finished; + }; struct GNUNET_FS_Namespace diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index b4f16518d..c86759c5f 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -710,6 +710,39 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) } +/** + * Check if all child-downloads have completed and + * if so, signal completion (and possibly recurse to + * parent). + */ +static void +check_completed (struct GNUNET_FS_DownloadContext *dc) +{ + struct GNUNET_FS_ProgressInfo pi; + struct GNUNET_FS_DownloadContext *pos; + + pos = dc->child_head; + while (pos != NULL) + { + if ( (pos->emsg == NULL) && + (pos->completed < pos->length) ) + return; /* not done yet */ + if ( (pos->child_head != NULL) && + (pos->has_finished != GNUNET_YES) ) + return; /* not transitively done yet */ + pos = pos->next; + } + dc->has_finished = GNUNET_YES; + /* signal completion */ + pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED; + make_download_status (&pi, dc); + dc->client_info = dc->h->upcb (dc->h->upcb_cls, + &pi); + if (dc->parent != NULL) + check_completed (dc->parent); +} + + /** * Iterator over entries in the pending requests in the 'active' map for the * reply that we just got. @@ -918,6 +951,8 @@ process_result_with_request (void *cls, make_download_status (&pi, dc); dc->client_info = dc->h->upcb (dc->h->upcb_cls, &pi); + if (dc->parent != NULL) + check_completed (dc->parent); } GNUNET_assert (sm->depth == dc->treedepth); } -- 2.25.1