From: Christian Grothoff Date: Mon, 3 May 2010 21:35:44 +0000 (+0000) Subject: towards suspend X-Git-Tag: initial-import-from-subversion-38251~21904 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=7eb4b4b3ab14ef6433b08cca8c673d00f8405062;p=oweals%2Fgnunet.git towards suspend --- diff --git a/TODO b/TODO index 88d5d2877..c9141e21f 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,8 @@ 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) - code review: => refactor fs.c to join common code segments! @@ -9,9 +11,6 @@ - persistence testing (publish, unindex, search, download): => need driver! => schedule suspending tasks DURING event handler => good coverage! - - track top-level operations in FS_Handle (needed for SUSPEND signalling) - - generate SUSPEND events (publish, unindex, search, download) AND free memory! - => test SUSPEND events - gnunet-service-fs (hot-path routing, load-based routing, nitpicks) - [gnunet-service-fs.c:208]: member 'LocalGetContext::results_bf_size' is never used - [gnunet-service-fs.c:501]: member 'PendingRequest::used_pids_size' is never used diff --git a/src/fs/fs.c b/src/fs/fs.c index f0753eee2..d0e73b21a 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c @@ -212,6 +212,49 @@ GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) } +/** + * Create a top-level activity entry. + * + * @param h global fs handle + * @param ssf suspend signal function to use + * @param ssf_cls closure for ssf + * @return fresh top-level activity handle + */ +struct TopLevelActivity * +GNUNET_FS_make_top (struct GNUNET_FS_Handle *h, + SuspendSignalFunction ssf, + void *ssf_cls) +{ + struct TopLevelActivity *ret; + + ret = GNUNET_malloc (sizeof (struct TopLevelActivity)); + ret->ssf = ssf; + ret->ssf_cls = ssf_cls; + GNUNET_CONTAINER_DLL_insert (h->top_head, + h->top_tail, + ret); + return ret; +} + + +/** + * Destroy a top-level activity entry. + * + * @param h global fs handle + * @param top top level activity entry + */ +void +GNUNET_FS_end_top (struct GNUNET_FS_Handle *h, + struct TopLevelActivity *top) +{ + GNUNET_CONTAINER_DLL_remove (h->top_head, + h->top_tail, + top); + GNUNET_free (top); +} + + + /** * Closure for "data_reader_file". */ @@ -2513,10 +2556,9 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, void GNUNET_FS_stop (struct GNUNET_FS_Handle *h) { - if (0 != (GNUNET_FS_FLAGS_PERSISTENCE & h->flags)) - { - // FIXME: generate SUSPEND events and clean up state! - } + /* generate SUSPEND events and clean up state */ + while (h->top_head != NULL) + h->top_head->ssf (h->top_head->ssf_cls); // FIXME: terminate receive-loop with client (do we need one?) if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (h->sched, diff --git a/src/fs/fs.h b/src/fs/fs.h index 7b30367ea..275882c4f 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -158,7 +158,14 @@ */ struct ContentHashKey { + /** + * Hash of the original content, used for encryption. + */ GNUNET_HashCode key; + + /** + * Hash of the encrypted content, used for querying. + */ GNUNET_HashCode query; }; @@ -212,15 +219,42 @@ struct Location }; +/** + * Types of URIs. + */ enum uri_types -{ chk, sks, ksk, loc }; + { + /** + * Content-hash-key (simple file). + */ + chk, + + /** + * Signed key space (file in namespace). + */ + sks, + + /** + * Keyword search key (query with keywords). + */ + ksk, + + /** + * Location (chk with identity of hosting peer). + */ + loc + }; /** * A Universal Resource Identifier (URI), opaque. */ struct GNUNET_FS_Uri { + /** + * Type of the URI. + */ enum uri_types type; + union { struct @@ -929,6 +963,68 @@ void GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc); +/** + * Function signature of the functions that can be called + * to trigger suspend signals and clean-up for top-level + * activities. + * + * @param cls closure + */ +typedef void (*SuspendSignalFunction)(void *cls); + +/** + * We track all of the top-level activities of FS + * so that we can signal 'suspend' on shutdown. + */ +struct TopLevelActivity +{ + /** + * This is a doubly-linked list. + */ + struct TopLevelActivity *next; + + /** + * This is a doubly-linked list. + */ + struct TopLevelActivity *prev; + + /** + * Function to call for suspend-signalling and clean up. + */ + SuspendSignalFunction ssf; + + /** + * Closure for 'ssf' (some struct GNUNET_FS_XXXHandle*) + */ + void *ssf_cls; +}; + + +/** + * Create a top-level activity entry. + * + * @param h global fs handle + * @param ssf suspend signal function to use + * @param ssf_cls closure for ssf + * @return fresh top-level activity handle + */ +struct TopLevelActivity * +GNUNET_FS_make_top (struct GNUNET_FS_Handle *h, + SuspendSignalFunction ssf, + void *ssf_cls); + + +/** + * Destroy a top-level activity entry. + * + * @param h global fs handle + * @param top top level activity entry + */ +void +GNUNET_FS_end_top (struct GNUNET_FS_Handle *h, + struct TopLevelActivity *top); + + /** * Master context for most FS operations. */ @@ -964,6 +1060,16 @@ struct GNUNET_FS_Handle */ struct GNUNET_CLIENT_Connection *client; + /** + * Head of DLL of top-level activities. + */ + struct TopLevelActivity *top_head; + + /** + * Tail of DLL of top-level activities. + */ + struct TopLevelActivity *top_tail; + /** * Head of DLL of running jobs. */ @@ -1034,6 +1140,11 @@ struct GNUNET_FS_PublishContext */ struct GNUNET_FS_Handle *h; + /** + * Our top-level activity entry (if we are top-level, otherwise NULL). + */ + struct TopLevelActivity *top; + /** * File-structure that is being shared. */ @@ -1162,6 +1273,11 @@ struct GNUNET_FS_UnindexContext */ struct GNUNET_FS_Handle *h; + /** + * Our top-level activity entry. + */ + struct TopLevelActivity *top; + /** * Name of the file that we are unindexing. */ @@ -1273,6 +1389,11 @@ struct GNUNET_FS_SearchContext */ struct GNUNET_FS_Handle *h; + /** + * Our top-level activity entry (if we are top-level, otherwise NULL). + */ + struct TopLevelActivity *top; + /** * List of keywords that we're looking for. */ @@ -1420,6 +1541,11 @@ struct GNUNET_FS_DownloadContext * Global FS context. */ struct GNUNET_FS_Handle *h; + + /** + * Our top-level activity entry (if we are top-level, otherwise NULL). + */ + struct TopLevelActivity *top; /** * Connection to the FS service. diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 6390539bc..bf59918e7 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -1383,6 +1383,23 @@ deactivate_fs_download (void *cls) } +/** + * Create SUSPEND event for the given download operation + * and then clean up our state (without stop signal). + * + * @param cls the 'struct GNUNET_FS_UnindexContext' to signal for + */ +static void +download_signal_suspend (void *cls) +{ + struct GNUNET_FS_DownloadContext *dc = cls; + + GNUNET_FS_end_top (dc->h, dc->top); + /* FIXME: signal! */ + GNUNET_free (dc); +} + + /** * Download parts of a file. Note that this will store * the blocks at the respective offset in the given file. Also, the @@ -1496,6 +1513,11 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, 0, 1 /* 0 == CHK, 1 == top */); GNUNET_FS_download_start_downloading_ (dc); + if (parent == NULL) + dc->top = GNUNET_FS_make_top (dc->h, + &download_signal_suspend, + dc); + return dc; } @@ -1665,6 +1687,8 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, { struct GNUNET_FS_ProgressInfo pi; + if (dc->top != NULL) + GNUNET_FS_end_top (dc->h, dc->top); if (dc->search != NULL) { dc->search->download = NULL; diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index c4dbe624e..4101174bb 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -929,6 +929,22 @@ fip_signal_start(void *cls, } +/** + * Create SUSPEND event for the given publish operation + * and then clean up our state (without stop signal). + * + * @param cls the 'struct GNUNET_FS_PublishContext' to signal for + */ +static void +publish_signal_suspend (void *cls) +{ + struct GNUNET_FS_PublishContext *pc = cls; + + GNUNET_FS_end_top (pc->h, pc->top); + /* FIXME: signal! */ + GNUNET_free (pc); +} + /** * Publish a file or directory. * @@ -983,7 +999,7 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, &fip_signal_start, ret); ret->fi_pos = ret->fi; - + ret->top = GNUNET_FS_make_top (h, &publish_signal_suspend, ret); // FIXME: calculate space needed for "fi" // and reserve as first task (then trigger // "publish_main" from that continuation)! @@ -1056,6 +1072,7 @@ fip_signal_stop(void *cls, void GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc) { + GNUNET_FS_end_top (pc->h, pc->top); if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task) GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task); if (pc->serialization != NULL) diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 611a089c4..00909ce97 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -1161,6 +1161,21 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) } +/** + * Create SUSPEND event for the given search operation + * and then clean up our state (without stop signal). + * + * @param cls the 'struct GNUNET_FS_SearchContext' to signal for + */ +static void +search_signal_suspend (void *cls) +{ + struct GNUNET_FS_SearchContext *sc = cls; + + GNUNET_FS_end_top (sc->h, sc->top); + /* FIXME: signal! */ + GNUNET_free (sc); +} /** @@ -1181,7 +1196,10 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h, enum GNUNET_FS_SearchOptions options, void *cctx) { - return search_start (h, uri, anonymity, options, cctx, NULL); + struct GNUNET_FS_SearchContext *ret; + ret = search_start (h, uri, anonymity, options, cctx, NULL); + ret->top = GNUNET_FS_make_top (h, &search_signal_suspend, ret); + return ret; } @@ -1253,6 +1271,7 @@ search_result_free (void *cls, pi.status = GNUNET_FS_STATUS_DOWNLOAD_LOST_PARENT; GNUNET_FS_download_make_status_ (&pi, sr->download); + /* FIXME: promote download to top-level! */ sr->download = NULL; } pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; @@ -1298,6 +1317,8 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) unsigned int i; struct GNUNET_FS_SearchContext *parent; + if (sc->top != NULL) + GNUNET_FS_end_top (sc->h, sc->top); // FIXME: make un-persistent! if (NULL != (parent = sc->parent)) { diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 4b4e526dd..6d4ee3f54 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -393,6 +393,23 @@ GNUNET_FS_unindex_process_hash_ (void *cls, } +/** + * Create SUSPEND event for the given unindex operation + * and then clean up our state (without stop signal). + * + * @param cls the 'struct GNUNET_FS_UnindexContext' to signal for + */ +static void +unindex_signal_suspend (void *cls) +{ + struct GNUNET_FS_UnindexContext *uc = cls; + + GNUNET_FS_end_top (uc->h, uc->top); + /* FIXME: signal! */ + GNUNET_free (uc); +} + + /** * Unindex a file. * @@ -432,6 +449,9 @@ GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h, HASHING_BLOCKSIZE, &GNUNET_FS_unindex_process_hash_, ret); + ret->top = GNUNET_FS_make_top (h, + &unindex_signal_suspend, + ret); return ret; } @@ -446,6 +466,7 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) { struct GNUNET_FS_ProgressInfo pi; + GNUNET_FS_end_top (uc->h, uc->top); if ( (uc->state != UNINDEX_STATE_COMPLETE) && (uc->state != UNINDEX_STATE_ERROR) ) {