deserialize search link to download
authorChristian Grothoff <christian@grothoff.org>
Tue, 4 May 2010 07:16:28 +0000 (07:16 +0000)
committerChristian Grothoff <christian@grothoff.org>
Tue, 4 May 2010 07:16:28 +0000 (07:16 +0000)
TODO
src/fs/fs.c
src/fs/fs_download.c
src/fs/fs_search.c

diff --git a/TODO b/TODO
index c9141e21fc688b69e0d3d02742d5e45c8f3a0ac3..861e2915d9012646a70d44347ac9e43f8f5fb9f3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 0.9.0pre1:
 * FS: [CG]
-  - implement linking of downloads to searches in syncing (serialize/deserialize) 
   - generate SUSPEND events (publish, unindex, search, download) AND free memory!
     => test SUSPEND events
   - actually call 'sync' functions (publish, unindex, search, download)
index d0e73b21a6e38554f3cdb7449e492031db49fa1b..371568ddfff4c92c7f96af166484e319e68f9cf6 100644 (file)
@@ -1546,6 +1546,8 @@ GNUNET_FS_search_result_sync_ (const GNUNET_HashCode *key,
   uris = GNUNET_FS_uri_to_string (sr->uri);
   if ( (GNUNET_OK !=
        GNUNET_BIO_write_string (wh, uris)) ||
+       (GNUNET_OK !=
+       GNUNET_BIO_write_string (wh, sr->download != NULL ? sr->download->serialization : NULL)) ||
        (GNUNET_OK !=
        GNUNET_BIO_write_meta_data (wh, sr->meta)) ||
        (GNUNET_OK !=
@@ -1804,6 +1806,23 @@ deserialize_unindex (struct GNUNET_FS_Handle *h)
 }
 
 
+/**
+ * Deserialize a download.
+ *
+ * @param h overall context
+ * @param rh file to deserialize from
+ * @param parent parent download
+ * @param search associated search
+ * @param serialization name under which the search was serialized
+ */
+static void
+deserialize_download (struct GNUNET_FS_Handle *h,
+                     struct GNUNET_BIO_ReadHandle *rh,
+                     struct GNUNET_FS_DownloadContext *parent,
+                     struct GNUNET_FS_SearchResult *search,
+                     const char *serialization);
+
+
 /**
  * Function called with a filename of serialized search result
  * to deserialize.
@@ -1821,7 +1840,9 @@ deserialize_search_result (void *cls,
   char *ser;
   char *uris;
   char *emsg;
+  char *download;
   struct GNUNET_BIO_ReadHandle *rh;
+  struct GNUNET_BIO_ReadHandle *drh;
   struct GNUNET_FS_SearchResult *sr;
   GNUNET_HashCode key;
 
@@ -1844,6 +1865,7 @@ deserialize_search_result (void *cls,
     }
   emsg = NULL;
   uris = NULL;
+  download = NULL;
   sr = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchResult));
   sr->serialization = ser;  
   if ( (GNUNET_OK !=
@@ -1851,6 +1873,8 @@ deserialize_search_result (void *cls,
        (NULL == (sr->uri = GNUNET_FS_uri_parse (uris, &emsg))) ||       
        ( (GNUNET_YES != GNUNET_FS_uri_test_chk (sr->uri)) &&
         (GNUNET_YES != GNUNET_FS_uri_test_loc (sr->uri)) ) ||
+       (GNUNET_OK !=
+       GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) ||
        (GNUNET_OK !=
        GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) ||
        (GNUNET_OK !=
@@ -1865,12 +1889,34 @@ deserialize_search_result (void *cls,
        GNUNET_BIO_read_int32 (rh, &sr->availability_trials)) )
     goto cleanup;   
   GNUNET_free (uris);
+  if (download != NULL)
+    {
+      drh = get_read_handle (sc->h, 
+                            "subdownloads",
+                            download);
+      deserialize_download (sc->h,
+                           drh,
+                           NULL,
+                           sr,
+                           download);
+      if (GNUNET_OK !=
+         GNUNET_BIO_read_close (drh, &emsg))
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                     _("Failed to resume sub-download `%s': %s\n"),
+                     download,
+                     emsg);
+         GNUNET_free (emsg);
+       }
+      GNUNET_free (download);
+    }
   GNUNET_CONTAINER_multihashmap_put (sc->master_result_map,
                                     &key,
                                     sr,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
   return GNUNET_OK;
  cleanup:
+  GNUNET_free_non_null (download);
   GNUNET_free_non_null (emsg);
   GNUNET_free_non_null (uris);
   if (sr->uri != NULL)
@@ -1883,6 +1929,36 @@ deserialize_search_result (void *cls,
 }
 
 
+/**
+ * Send the 'resume' signal to the callback; also actually
+ * resume the download (put it in the queue).  Does this
+ * recursively for the top-level download and all child
+ * downloads.
+ * 
+ * @param dc download to resume
+ */
+static void
+signal_download_resume (struct GNUNET_FS_DownloadContext *dc)
+{
+  struct GNUNET_FS_DownloadContext *dcc;
+  struct GNUNET_FS_ProgressInfo pi;
+  
+  pi.status = GNUNET_FS_STATUS_DOWNLOAD_RESUME;
+  pi.value.download.specifics.resume.meta = dc->meta;
+  pi.value.download.specifics.resume.message = dc->emsg;
+  GNUNET_FS_download_make_status_ (&pi,
+                                  dc);
+  dcc = dc->child_head;
+  while (NULL != dcc)
+    {
+      signal_download_resume (dcc);
+      dcc = dcc->next;
+    }
+  if (dc->pending != NULL)
+    GNUNET_FS_download_start_downloading_ (dc);
+}
+
+
 /**
  * Iterator over search results signaling resume to the client for
  * each result.
@@ -1913,7 +1989,14 @@ signal_result_resume (void *cls,
       sr->client_info = GNUNET_FS_search_make_status_ (&pi,
                                                       sc);
     }
-  GNUNET_FS_search_start_probe_ (sr);
+  if (sr->download != NULL)
+    {
+      signal_download_resume (sr->download);
+    }
+  else
+    {
+      GNUNET_FS_search_start_probe_ (sr);
+    }
   return GNUNET_YES;
 }
 
@@ -1975,21 +2058,6 @@ free_search_context (struct GNUNET_FS_SearchContext *sc)
 }
 
 
-/**
- * Deserialize a download.
- *
- * @param h overall context
- * @param rh file to deserialize from
- * @param parent parent download
- * @param serialization name under which the search was serialized
- */
-static void
-deserialize_download (struct GNUNET_FS_Handle *h,
-                     struct GNUNET_BIO_ReadHandle *rh,
-                     struct GNUNET_FS_DownloadContext *parent,
-                     const char *serialization);
-
-
 /**
  * Function called with a filename of serialized sub-download
  * to deserialize.
@@ -2012,6 +2080,7 @@ deserialize_subdownload (void *cls,
   deserialize_download (parent->h,
                        rh,
                        parent,
+                       NULL,
                        ser);
   if (GNUNET_OK !=
       GNUNET_BIO_read_close (rh, &emsg))
@@ -2027,36 +2096,6 @@ deserialize_subdownload (void *cls,
 }
 
 
-/**
- * Send the 'resume' signal to the callback; also actually
- * resume the download (put it in the queue).  Does this
- * recursively for the top-level download and all child
- * downloads.
- * 
- * @param dc download to resume
- */
-static void
-signal_download_resume (struct GNUNET_FS_DownloadContext *dc)
-{
-  struct GNUNET_FS_DownloadContext *dcc;
-  struct GNUNET_FS_ProgressInfo pi;
-  
-  pi.status = GNUNET_FS_STATUS_DOWNLOAD_RESUME;
-  pi.value.download.specifics.resume.meta = dc->meta;
-  pi.value.download.specifics.resume.message = dc->emsg;
-  GNUNET_FS_download_make_status_ (&pi,
-                                  dc);
-  dcc = dc->child_head;
-  while (NULL != dcc)
-    {
-      signal_download_resume (dcc);
-      dcc = dcc->next;
-    }
-  if (dc->pending != NULL)
-    GNUNET_FS_download_start_downloading_ (dc);
-}
-
-
 /**
  * Free this download context and all of its descendants.
  * (only works during deserialization since not all possible
@@ -2098,12 +2137,14 @@ free_download_context (struct GNUNET_FS_DownloadContext *dc)
  * @param h overall context
  * @param rh file to deserialize from
  * @param parent parent download
+ * @param search associated search
  * @param serialization name under which the search was serialized
  */
 static void
 deserialize_download (struct GNUNET_FS_Handle *h,
                      struct GNUNET_BIO_ReadHandle *rh,
                      struct GNUNET_FS_DownloadContext *parent,
+                     struct GNUNET_FS_SearchResult *search,
                      const char *serialization)
 {
   struct GNUNET_FS_DownloadContext *dc;
@@ -2197,6 +2238,11 @@ deserialize_download (struct GNUNET_FS_Handle *h,
     GNUNET_CONTAINER_DLL_insert (parent->child_head,
                                 parent->child_tail,
                                 dc);
+  if (search != NULL)
+    {
+      dc->search = search;
+      search->download = dc;
+    }
   signal_download_resume (dc);
   GNUNET_free (uris);
   return;
@@ -2437,7 +2483,7 @@ deserialize_download_file (void *cls,
        }
       return GNUNET_OK;
     }
-  deserialize_download (h, rh, NULL, ser);
+  deserialize_download (h, rh, NULL, NULL, ser);
   GNUNET_free (ser);
   if (GNUNET_OK !=
       GNUNET_BIO_read_close (rh, &emsg))
index bf59918e7534f47adfade0b52fb59b5efef1669c..d7c5370b1f0dd3dccf8d90348f83800abdba9a09 100644 (file)
@@ -1592,6 +1592,11 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h,
   dc->h = h;
   dc->search = sr;
   sr->download = dc;
+  if (sr->probe_ctx != NULL)
+    {
+      GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
+      sr->probe_ctx = NULL;      
+    }
   dc->uri = GNUNET_FS_uri_dup (sr->uri);
   dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta);
   dc->client_info = cctx;
index 00909ce97f42b8d2b5ab22fa911610b3d1655fc8..9ab024eeb09d9010f44d2cc71ddcd614608b8535 100644 (file)
@@ -301,7 +301,12 @@ GNUNET_FS_search_probe_progress_ (void *cls,
                                                            sr);
       break;
     case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
-      /* FIXME: clean up? schedule next probe? or already done? */
+      if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+       {
+         GNUNET_SCHEDULER_cancel (sr->sc->h->sched,
+                                  sr->probe_cancel_task);
+         sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
+       }     
       sr = NULL;
       break;
     case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
@@ -344,6 +349,8 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr)
   
   if (sr->probe_ctx != NULL)
     return;
+  if (sr->download != NULL)
+    return;
   if (0 == (sr->sc->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
     return;
   if (sr->availability_trials > AVAILABILITY_TRIALS_MAX)