fix
authorChristian Grothoff <christian@grothoff.org>
Fri, 2 Apr 2010 20:58:19 +0000 (20:58 +0000)
committerChristian Grothoff <christian@grothoff.org>
Fri, 2 Apr 2010 20:58:19 +0000 (20:58 +0000)
TODO
src/fs/fs.h
src/fs/fs_download.c

diff --git a/TODO b/TODO
index 49e6476718f4b0e20aeaea207075971e7b2fd85b..22c52e934144d6f3c0265b6f86fb9e72ca853300 100644 (file)
--- 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!]
index 0b3b2595578d67ffa9877efa332b19cadb31ccb8..3a42fee2d072fb72ee771e265c825215817d1de0 100644 (file)
@@ -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
index b4f16518ddb2638bec64f3c7ccc61c52a83cb77b..c86759c5f14390d0efe9b1f8f25992b4035faf97 100644 (file)
@@ -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);
     }