From 3cbee1d6d6d396b45e88f7f0e6f1b5a21e9f2f77 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 4 May 2010 07:16:28 +0000 Subject: [PATCH] deserialize search link to download --- TODO | 1 - src/fs/fs.c | 140 ++++++++++++++++++++++++++++--------------- src/fs/fs_download.c | 5 ++ src/fs/fs_search.c | 9 ++- 4 files changed, 106 insertions(+), 49 deletions(-) diff --git a/TODO b/TODO index c9141e21f..861e2915d 100644 --- 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) diff --git a/src/fs/fs.c b/src/fs/fs.c index d0e73b21a..371568ddf 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c @@ -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)) diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index bf59918e7..d7c5370b1 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -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; diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 00909ce97..9ab024eeb 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -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) -- 2.25.1