From 38d63ac3806899f5eb4d9ff9dca8581a72e3fb9a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 18 Oct 2009 20:23:21 +0000 Subject: more work on bugs and testing of fs service --- src/fs/fs.h | 5 +++ src/fs/fs_file_information.c | 45 ++++++++++++++------------ src/fs/fs_publish.c | 13 ++++++-- src/fs/fs_tree.c | 1 + src/fs/test_fs_download.c | 68 ++++++++++++++++++++++----------------- src/fs/test_fs_download_data.conf | 1 + src/include/gnunet_fs_service.h | 1 + 7 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/fs/fs.h b/src/fs/fs.h index a9fa712c6..f335888ef 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -552,6 +552,11 @@ struct GNUNET_FS_PublishContext * for this upload. */ int rid; + + /** + * Set to GNUNET_YES if all processing has completed. + */ + int all_done; }; diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 9bdc30262..6d6a83ffe 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c @@ -249,6 +249,7 @@ data_reader_copy(void *cls, char **emsg) { char *data = cls; + if (max == 0) { GNUNET_free (data); @@ -343,6 +344,7 @@ GNUNET_FS_file_information_create_from_reader (void *client_info, ret->data.file.reader = reader; ret->data.file.reader_cls = reader_cls; ret->data.file.do_index = do_index; + ret->data.file.file_size = length; ret->anonymity = anonymity; ret->priority = priority; GNUNET_FS_file_information_sync (ret); @@ -803,15 +805,16 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls); } /* clean up client-info */ - cleaner (cleaner_cls, - fi, - fi->data.dir.dir_size, - fi->meta, - &fi->keywords, - &fi->anonymity, - &fi->priority, - &fi->expirationTime, - &fi->client_info); + if (NULL != cleaner) + cleaner (cleaner_cls, + fi, + fi->data.dir.dir_size, + fi->meta, + &fi->keywords, + &fi->anonymity, + &fi->priority, + &fi->expirationTime, + &fi->client_info); GNUNET_free_non_null (fi->data.dir.dir_data); GNUNET_free (fi->data.dir.dirname); } @@ -820,25 +823,27 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, /* call clean-up function of the reader */ fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL); /* clean up client-info */ - cleaner (cleaner_cls, - fi, - fi->data.file.file_size, - fi->meta, - &fi->keywords, - &fi->anonymity, - &fi->priority, - &fi->expirationTime, - &fi->client_info); + if (NULL != cleaner) + cleaner (cleaner_cls, + fi, + fi->data.file.file_size, + fi->meta, + &fi->keywords, + &fi->anonymity, + &fi->priority, + &fi->expirationTime, + &fi->client_info); } GNUNET_free_non_null (fi->emsg); /* clean up serialization */ - if (0 != UNLINK (fi->serialization)) + if ( (NULL != fi->serialization) && + (0 != UNLINK (fi->serialization)) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fi->serialization); GNUNET_FS_uri_destroy (fi->keywords); GNUNET_CONTAINER_meta_data_destroy (fi->meta); - GNUNET_free (fi->serialization); + GNUNET_free_non_null (fi->serialization); GNUNET_free (fi); } diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 3ccc3c97a..f8c76c36b 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -135,7 +135,8 @@ static void publish_cleanup (struct GNUNET_FS_PublishContext *sc) { GNUNET_FS_file_information_destroy (sc->fi, NULL, NULL); - GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO); + if (sc->namespace != NULL) + GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO); GNUNET_free_non_null (sc->nid); GNUNET_free_non_null (sc->nuid); GNUNET_DATASTORE_disconnect (sc->dsh, GNUNET_NO); @@ -181,7 +182,6 @@ ds_put_cont (void *cls, pcc->p->client_info = pcc->sc->h->upcb (pcc->sc->h->upcb_cls, &pi); - return; } GNUNET_FS_file_information_sync (pcc->p); if (NULL != pcc->cont) @@ -272,6 +272,7 @@ publish_sblocks_cont (void *cls, } // FIXME: release the datastore reserve here! signal_publish_completion (sc->fi, sc); + sc->all_done = GNUNET_YES; } @@ -392,6 +393,9 @@ block_reader (void *cls, { pt_size = GNUNET_MIN(max, p->data.file.file_size - offset); + if (pt_size == 0) + return 0; /* calling reader with pt_size==0 + might free buf, so don't! */ if (pt_size != p->data.file.reader (p->data.file.reader_cls, offset, @@ -498,6 +502,7 @@ block_proc (void *cls, dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx)); dpc_cls->cont = &do_upload; dpc_cls->cont_cls = sc; + dpc_cls->sc = sc; dpc_cls->p = p; if ( (p->is_directory) && (p->data.file.do_index) && @@ -833,6 +838,7 @@ do_upload (void *cls, = sc->h->upcb (sc->h->upcb_cls, &pi); } + sc->all_done = GNUNET_YES; return; } /* handle completion */ @@ -1034,6 +1040,7 @@ fip_signal_stop(void *cls, * Stop an upload. Will abort incomplete uploads (but * not remove blocks that have already been publishd) or * simply clean up the state for completed uploads. + * Must NOT be called from within the event callback! * * @param sc context for the upload to stop */ @@ -1042,6 +1049,8 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc) { if (GNUNET_SCHEDULER_NO_TASK != sc->upload_task) GNUNET_SCHEDULER_cancel (sc->h->sched, sc->upload_task); + else + GNUNET_assert (sc->all_done == GNUNET_YES); // FIXME: remove from persistence DB (?) --- think more about // shutdown / persistent-resume APIs!!! GNUNET_FS_file_information_inspect (sc->fi, diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c index d151eb086..b409080db 100644 --- a/src/fs/fs_tree.c +++ b/src/fs/fs_tree.c @@ -171,6 +171,7 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, { struct GNUNET_FS_TreeEncoder *te; + GNUNET_assert (size > 0); te = GNUNET_malloc (sizeof (struct GNUNET_FS_TreeEncoder)); te->h = h; te->size = size; diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c index dbdc12fec..ffb90d678 100644 --- a/src/fs/test_fs_download.c +++ b/src/fs/test_fs_download.c @@ -69,6 +69,24 @@ static struct GNUNET_FS_PublishContext *publish; static char *fn; +static void +abort_download_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_FS_download_stop (download, GNUNET_YES); + download = NULL; +} + + +static void +abort_publish_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_FS_publish_stop (publish); + publish = NULL; +} + + static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) @@ -76,14 +94,8 @@ progress_cb (void *cls, switch (event->status) { - case GNUNET_FS_STATUS_DOWNLOAD_SUSPEND: - GNUNET_break (0); - break; - case GNUNET_FS_STATUS_DOWNLOAD_RESUME: - GNUNET_break (0); - break; case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if DEBUG_VERBOSE > 1 +#if DEBUG_VERBOSE printf ("Publish is progressing (%llu/%llu)...\n", (unsigned long long) event->value.publish.completed, (unsigned long long) event->value.publish.size); @@ -115,35 +127,39 @@ progress_cb (void *cls, download = NULL; break; case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: -#if DEBUG_VERBOSE > 1 +#if DEBUG_VERBOSE printf ("Download is progressing (%llu/%llu)...\n", (unsigned long long) event->value.download.completed, (unsigned long long) event->value.download.size); #endif break; - case GNUNET_FS_STATUS_UNINDEX_PROGRESS: - GNUNET_break (0); - break; - case GNUNET_FS_STATUS_UNINDEX_COMPLETED: - GNUNET_break (0); - break; - case GNUNET_FS_STATUS_UNINDEX_ERROR: - GNUNET_break (0); case GNUNET_FS_STATUS_PUBLISH_ERROR: + fprintf (stderr, + "Error publishing file: %s\n", + event->value.publish.specifics.error.message); GNUNET_break (0); - case GNUNET_FS_STATUS_DOWNLOAD_ERROR: - GNUNET_break (0); - break; - case GNUNET_FS_STATUS_UNINDEX_SUSPEND: - GNUNET_break (0); + GNUNET_SCHEDULER_add_continuation (sched, + GNUNET_NO, + &abort_publish_task, + NULL, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; - case GNUNET_FS_STATUS_PUBLISH_SUSPEND: - GNUNET_break (0); + case GNUNET_FS_STATUS_DOWNLOAD_ERROR: + fprintf (stderr, + "Error downloading file: %s\n", + event->value.download.specifics.error.message); + GNUNET_SCHEDULER_add_continuation (sched, + GNUNET_NO, + &abort_download_task, + NULL, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; case GNUNET_FS_STATUS_PUBLISH_START: /* FIXME: add checks here... */ + break; case GNUNET_FS_STATUS_PUBLISH_STOPPED: /* FIXME: add checks here... */ + break; case GNUNET_FS_STATUS_DOWNLOAD_START: /* FIXME: add checks here... */ break; @@ -152,12 +168,6 @@ progress_cb (void *cls, GNUNET_FS_stop (fs); fs = NULL; break; - case GNUNET_FS_STATUS_UNINDEX_START: - GNUNET_break (0); - break; - case GNUNET_FS_STATUS_UNINDEX_STOPPED: - GNUNET_break (0); - break; default: printf ("Unexpected event: %d\n", event->status); diff --git a/src/fs/test_fs_download_data.conf b/src/fs/test_fs_download_data.conf index 6cc9c23a8..ac90b3203 100644 --- a/src/fs/test_fs_download_data.conf +++ b/src/fs/test_fs_download_data.conf @@ -16,6 +16,7 @@ PLUGINS = [arm] PORT = 42466 HOSTNAME = localhost +DEFAULTSERVICES = resolver datastore transport core fs [statistics] PORT = 42467 diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 21ffe299a..7c15358e8 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h @@ -1902,6 +1902,7 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, * Stop an upload. Will abort incomplete uploads (but * not remove blocks that have already been publishd) or * simply clean up the state for completed uploads. + * Must NOT be called from within the event callback! * * @param sc context for the upload to stop */ -- cgit v1.2.3