make clang static analysis happy
[oweals/gnunet.git] / src / fs / fs_download.c
index b4f16518ddb2638bec64f3c7ccc61c52a83cb77b..6e215ed27a98025de3769e98f1c5cda7dee6ab96 100644 (file)
@@ -175,8 +175,7 @@ transmit_download_request (void *cls,
 
 
 /**
- * Schedule the download of the specified
- * block in the tree.
+ * Schedule the download of the specified block in the tree.
  *
  * @param dc overall download this block belongs to
  * @param chk content-hash-key of the block
@@ -710,6 +709,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.
@@ -873,7 +905,6 @@ process_result_with_request (void *cls,
                                           dc);         
            
     }
-
   pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
   make_download_status (&pi, dc);
   pi.value.download.specifics.progress.data = pt;
@@ -918,6 +949,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);
     }
@@ -1289,7 +1322,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
   dc->length = length;
   dc->anonymity = anonymity;
   dc->options = options;
-  dc->active = GNUNET_CONTAINER_multihashmap_create (2 * (length / DBLOCK_SIZE));
+  dc->active = GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE));
   dc->treedepth = GNUNET_FS_compute_depth (GNUNET_ntohll(dc->uri->data.chk.file_length));
 #if DEBUG_DOWNLOAD
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,