diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fs/fs.c | 173 | ||||
-rw-r--r-- | src/fs/fs.h | 38 | ||||
-rw-r--r-- | src/fs/fs_search.c | 81 | ||||
-rw-r--r-- | src/include/gnunet_fs_service.h | 10 |
4 files changed, 147 insertions, 155 deletions
diff --git a/src/fs/fs.c b/src/fs/fs.c index f69fd564d..15fe86f71 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c | |||
@@ -1706,14 +1706,14 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) | |||
1706 | uris = NULL; | 1706 | uris = NULL; |
1707 | if (NULL == sr->serialization) | 1707 | if (NULL == sr->serialization) |
1708 | sr->serialization = make_serialization_file_name_in_dir (sr->sc->h, | 1708 | sr->serialization = make_serialization_file_name_in_dir (sr->sc->h, |
1709 | (sr->sc->parent == NULL) | 1709 | (sr->sc->psearch_result == NULL) |
1710 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 1710 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
1711 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 1711 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
1712 | sr->sc->serialization); | 1712 | sr->sc->serialization); |
1713 | if (NULL == sr->serialization) | 1713 | if (NULL == sr->serialization) |
1714 | return; | 1714 | return; |
1715 | wh = get_write_handle_in_dir (sr->sc->h, | 1715 | wh = get_write_handle_in_dir (sr->sc->h, |
1716 | (sr->sc->parent == NULL) | 1716 | (sr->sc->psearch_result == NULL) |
1717 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 1717 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
1718 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 1718 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
1719 | sr->sc->serialization, | 1719 | sr->sc->serialization, |
@@ -1724,6 +1724,8 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) | |||
1724 | (GNUNET_OK != | 1724 | (GNUNET_OK != |
1725 | GNUNET_BIO_write_string (wh, sr->download != NULL ? sr->download->serialization : NULL)) || | 1725 | GNUNET_BIO_write_string (wh, sr->download != NULL ? sr->download->serialization : NULL)) || |
1726 | (GNUNET_OK != | 1726 | (GNUNET_OK != |
1727 | GNUNET_BIO_write_string (wh, sr->update_search != NULL ? sr->update_search->serialization : NULL)) || | ||
1728 | (GNUNET_OK != | ||
1727 | GNUNET_BIO_write_meta_data (wh, sr->meta)) || | 1729 | GNUNET_BIO_write_meta_data (wh, sr->meta)) || |
1728 | (GNUNET_OK != | 1730 | (GNUNET_OK != |
1729 | GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) || | 1731 | GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) || |
@@ -1749,7 +1751,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) | |||
1749 | if (wh != NULL) | 1751 | if (wh != NULL) |
1750 | (void) GNUNET_BIO_write_close (wh); | 1752 | (void) GNUNET_BIO_write_close (wh); |
1751 | remove_sync_file_in_dir (sr->sc->h, | 1753 | remove_sync_file_in_dir (sr->sc->h, |
1752 | (sr->sc->parent == NULL) | 1754 | (sr->sc->psearch_result == NULL) |
1753 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 1755 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
1754 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 1756 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
1755 | sr->sc->serialization, | 1757 | sr->sc->serialization, |
@@ -1771,13 +1773,13 @@ void | |||
1771 | GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) | 1773 | GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) |
1772 | { | 1774 | { |
1773 | struct GNUNET_BIO_WriteHandle *wh; | 1775 | struct GNUNET_BIO_WriteHandle *wh; |
1774 | struct GNUNET_FS_SearchContext *scc; | ||
1775 | char *uris; | 1776 | char *uris; |
1776 | char in_pause; | 1777 | char in_pause; |
1777 | const char *category; | 1778 | const char *category; |
1778 | |||
1779 | 1779 | ||
1780 | category = (sc->parent == NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : GNUNET_FS_SYNC_PATH_CHILD_SEARCH; | 1780 | category = (sc->psearch_result == NULL) |
1781 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | ||
1782 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH; | ||
1781 | if (NULL == sc->serialization) | 1783 | if (NULL == sc->serialization) |
1782 | sc->serialization = make_serialization_file_name (sc->h, | 1784 | sc->serialization = make_serialization_file_name (sc->h, |
1783 | category); | 1785 | category); |
@@ -1803,17 +1805,6 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) | |||
1803 | goto cleanup; | 1805 | goto cleanup; |
1804 | GNUNET_free (uris); | 1806 | GNUNET_free (uris); |
1805 | uris = NULL; | 1807 | uris = NULL; |
1806 | scc = sc->child_head; | ||
1807 | while (NULL != scc) | ||
1808 | { | ||
1809 | if (scc->serialization == NULL) | ||
1810 | break; | ||
1811 | if (GNUNET_OK != | ||
1812 | GNUNET_BIO_write_string (wh, scc->serialization)) | ||
1813 | goto cleanup; | ||
1814 | scc = scc->next; | ||
1815 | } | ||
1816 | GNUNET_BIO_write_string (wh, NULL); | ||
1817 | if (GNUNET_OK != | 1808 | if (GNUNET_OK != |
1818 | GNUNET_BIO_write_close (wh)) | 1809 | GNUNET_BIO_write_close (wh)) |
1819 | { | 1810 | { |
@@ -1971,6 +1962,21 @@ deserialize_download (struct GNUNET_FS_Handle *h, | |||
1971 | 1962 | ||
1972 | 1963 | ||
1973 | /** | 1964 | /** |
1965 | * Deserialize a search. | ||
1966 | * | ||
1967 | * @param h overall context | ||
1968 | * @param rh file to deserialize from | ||
1969 | * @param psearch_result parent search result | ||
1970 | * @param serialization name under which the search was serialized | ||
1971 | */ | ||
1972 | static struct GNUNET_FS_SearchContext * | ||
1973 | deserialize_search (struct GNUNET_FS_Handle *h, | ||
1974 | struct GNUNET_BIO_ReadHandle *rh, | ||
1975 | struct GNUNET_FS_SearchResult *psearch_result, | ||
1976 | const char *serialization); | ||
1977 | |||
1978 | |||
1979 | /** | ||
1974 | * Function called with a filename of serialized search result | 1980 | * Function called with a filename of serialized search result |
1975 | * to deserialize. | 1981 | * to deserialize. |
1976 | * | 1982 | * |
@@ -1987,6 +1993,7 @@ deserialize_search_result (void *cls, | |||
1987 | char *uris; | 1993 | char *uris; |
1988 | char *emsg; | 1994 | char *emsg; |
1989 | char *download; | 1995 | char *download; |
1996 | char *update_srch; | ||
1990 | struct GNUNET_BIO_ReadHandle *rh; | 1997 | struct GNUNET_BIO_ReadHandle *rh; |
1991 | struct GNUNET_BIO_ReadHandle *drh; | 1998 | struct GNUNET_BIO_ReadHandle *drh; |
1992 | struct GNUNET_FS_SearchResult *sr; | 1999 | struct GNUNET_FS_SearchResult *sr; |
@@ -1998,7 +2005,7 @@ deserialize_search_result (void *cls, | |||
1998 | if (ser != NULL) | 2005 | if (ser != NULL) |
1999 | { | 2006 | { |
2000 | remove_sync_file_in_dir (sc->h, | 2007 | remove_sync_file_in_dir (sc->h, |
2001 | (sc->parent == NULL) | 2008 | (sc->psearch_result == NULL) |
2002 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 2009 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
2003 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 2010 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
2004 | sc->serialization, | 2011 | sc->serialization, |
@@ -2018,6 +2025,8 @@ deserialize_search_result (void *cls, | |||
2018 | (GNUNET_OK != | 2025 | (GNUNET_OK != |
2019 | GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) || | 2026 | GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) || |
2020 | (GNUNET_OK != | 2027 | (GNUNET_OK != |
2028 | GNUNET_BIO_read_string (rh, "search-lnk", &update_srch, 16)) || | ||
2029 | (GNUNET_OK != | ||
2021 | GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) || | 2030 | GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) || |
2022 | (GNUNET_OK != | 2031 | (GNUNET_OK != |
2023 | GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) || | 2032 | GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) || |
@@ -2052,6 +2061,26 @@ deserialize_search_result (void *cls, | |||
2052 | } | 2061 | } |
2053 | GNUNET_free (download); | 2062 | GNUNET_free (download); |
2054 | } | 2063 | } |
2064 | if (update_srch != NULL) | ||
2065 | { | ||
2066 | drh = get_read_handle (sc->h, | ||
2067 | GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | ||
2068 | update_srch); | ||
2069 | deserialize_search (sc->h, | ||
2070 | drh, | ||
2071 | sr, | ||
2072 | update_srch); | ||
2073 | if (GNUNET_OK != | ||
2074 | GNUNET_BIO_read_close (drh, &emsg)) | ||
2075 | { | ||
2076 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2077 | _("Failed to resume sub-search `%s': %s\n"), | ||
2078 | update_srch, | ||
2079 | emsg); | ||
2080 | GNUNET_free (emsg); | ||
2081 | } | ||
2082 | GNUNET_free (update_srch); | ||
2083 | } | ||
2055 | GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, | 2084 | GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, |
2056 | &sr->key, | 2085 | &sr->key, |
2057 | sr, | 2086 | sr, |
@@ -2102,6 +2131,16 @@ signal_download_resume (struct GNUNET_FS_DownloadContext *dc) | |||
2102 | 2131 | ||
2103 | 2132 | ||
2104 | /** | 2133 | /** |
2134 | * Signal resuming of a search to our clients (for the | ||
2135 | * top level search and all sub-searches). | ||
2136 | * | ||
2137 | * @param sc search being resumed | ||
2138 | */ | ||
2139 | static void | ||
2140 | signal_search_resume (struct GNUNET_FS_SearchContext *sc); | ||
2141 | |||
2142 | |||
2143 | /** | ||
2105 | * Iterator over search results signaling resume to the client for | 2144 | * Iterator over search results signaling resume to the client for |
2106 | * each result. | 2145 | * each result. |
2107 | * | 2146 | * |
@@ -2139,11 +2178,22 @@ signal_result_resume (void *cls, | |||
2139 | { | 2178 | { |
2140 | GNUNET_FS_search_start_probe_ (sr); | 2179 | GNUNET_FS_search_start_probe_ (sr); |
2141 | } | 2180 | } |
2181 | if (sr->update_search != NULL) | ||
2182 | signal_search_resume (sr->update_search); | ||
2142 | return GNUNET_YES; | 2183 | return GNUNET_YES; |
2143 | } | 2184 | } |
2144 | 2185 | ||
2145 | 2186 | ||
2146 | /** | 2187 | /** |
2188 | * Free memory allocated by the search context and its children | ||
2189 | * | ||
2190 | * @param sc search context to free | ||
2191 | */ | ||
2192 | static void | ||
2193 | free_search_context (struct GNUNET_FS_SearchContext *sc); | ||
2194 | |||
2195 | |||
2196 | /** | ||
2147 | * Iterator over search results freeing each. | 2197 | * Iterator over search results freeing each. |
2148 | * | 2198 | * |
2149 | * @param cls closure, the 'struct GNUNET_FS_SearchContext' | 2199 | * @param cls closure, the 'struct GNUNET_FS_SearchContext' |
@@ -2158,6 +2208,11 @@ free_result (void *cls, | |||
2158 | { | 2208 | { |
2159 | struct GNUNET_FS_SearchResult *sr = value; | 2209 | struct GNUNET_FS_SearchResult *sr = value; |
2160 | 2210 | ||
2211 | if (sr->update_search != NULL) | ||
2212 | { | ||
2213 | free_search_context (sr->update_search); | ||
2214 | GNUNET_assert (NULL == sr->update_search); | ||
2215 | } | ||
2161 | GNUNET_CONTAINER_meta_data_destroy (sr->meta); | 2216 | GNUNET_CONTAINER_meta_data_destroy (sr->meta); |
2162 | GNUNET_FS_uri_destroy (sr->uri); | 2217 | GNUNET_FS_uri_destroy (sr->uri); |
2163 | GNUNET_free (sr); | 2218 | GNUNET_free (sr); |
@@ -2173,30 +2228,21 @@ free_result (void *cls, | |||
2173 | static void | 2228 | static void |
2174 | free_search_context (struct GNUNET_FS_SearchContext *sc) | 2229 | free_search_context (struct GNUNET_FS_SearchContext *sc) |
2175 | { | 2230 | { |
2176 | struct GNUNET_FS_SearchContext *scc; | ||
2177 | |||
2178 | while (NULL != (scc = sc->child_head)) | ||
2179 | { | ||
2180 | GNUNET_CONTAINER_DLL_remove (sc->child_head, | ||
2181 | sc->child_tail, | ||
2182 | scc); | ||
2183 | free_search_context (scc); | ||
2184 | } | ||
2185 | GNUNET_free_non_null (sc->emsg); | ||
2186 | if (sc->serialization != NULL) | 2231 | if (sc->serialization != NULL) |
2187 | { | 2232 | { |
2188 | GNUNET_FS_remove_sync_file_ (sc->h, | 2233 | GNUNET_FS_remove_sync_file_ (sc->h, |
2189 | (sc->parent == NULL) | 2234 | (sc->psearch_result == NULL) |
2190 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 2235 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
2191 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 2236 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
2192 | sc->serialization); | 2237 | sc->serialization); |
2193 | GNUNET_FS_remove_sync_dir_ (sc->h, | 2238 | GNUNET_FS_remove_sync_dir_ (sc->h, |
2194 | (sc->parent == NULL) | 2239 | (sc->psearch_result == NULL) |
2195 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 2240 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
2196 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 2241 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
2197 | sc->serialization); | 2242 | sc->serialization); |
2198 | } | 2243 | } |
2199 | GNUNET_free_non_null (sc->serialization); | 2244 | GNUNET_free_non_null (sc->serialization); |
2245 | GNUNET_free_non_null (sc->emsg); | ||
2200 | if (sc->uri != NULL) | 2246 | if (sc->uri != NULL) |
2201 | GNUNET_FS_uri_destroy (sc->uri); | 2247 | GNUNET_FS_uri_destroy (sc->uri); |
2202 | if (sc->master_result_map != NULL) | 2248 | if (sc->master_result_map != NULL) |
@@ -2407,7 +2453,6 @@ deserialize_download (struct GNUNET_FS_Handle *h, | |||
2407 | static void | 2453 | static void |
2408 | signal_search_resume (struct GNUNET_FS_SearchContext *sc) | 2454 | signal_search_resume (struct GNUNET_FS_SearchContext *sc) |
2409 | { | 2455 | { |
2410 | struct GNUNET_FS_SearchContext *scc; | ||
2411 | struct GNUNET_FS_ProgressInfo pi; | 2456 | struct GNUNET_FS_ProgressInfo pi; |
2412 | 2457 | ||
2413 | pi.status = GNUNET_FS_STATUS_SEARCH_RESUME; | 2458 | pi.status = GNUNET_FS_STATUS_SEARCH_RESUME; |
@@ -2415,12 +2460,10 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc) | |||
2415 | pi.value.search.specifics.resume.is_paused = (sc->client == NULL) ? GNUNET_YES : GNUNET_NO; | 2460 | pi.value.search.specifics.resume.is_paused = (sc->client == NULL) ? GNUNET_YES : GNUNET_NO; |
2416 | sc->client_info = GNUNET_FS_search_make_status_ (&pi, | 2461 | sc->client_info = GNUNET_FS_search_make_status_ (&pi, |
2417 | sc); | 2462 | sc); |
2418 | scc = sc->child_head; | 2463 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, |
2419 | while (NULL != scc) | 2464 | &signal_result_resume, |
2420 | { | 2465 | sc); |
2421 | signal_search_resume (scc); | 2466 | |
2422 | scc = scc->next; | ||
2423 | } | ||
2424 | } | 2467 | } |
2425 | 2468 | ||
2426 | 2469 | ||
@@ -2429,29 +2472,36 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc) | |||
2429 | * | 2472 | * |
2430 | * @param h overall context | 2473 | * @param h overall context |
2431 | * @param rh file to deserialize from | 2474 | * @param rh file to deserialize from |
2432 | * @param parent parent search | 2475 | * @param psearch_result parent search result |
2433 | * @param serialization name under which the search was serialized | 2476 | * @param serialization name under which the search was serialized |
2434 | */ | 2477 | */ |
2435 | static struct GNUNET_FS_SearchContext * | 2478 | static struct GNUNET_FS_SearchContext * |
2436 | deserialize_search (struct GNUNET_FS_Handle *h, | 2479 | deserialize_search (struct GNUNET_FS_Handle *h, |
2437 | struct GNUNET_BIO_ReadHandle *rh, | 2480 | struct GNUNET_BIO_ReadHandle *rh, |
2438 | struct GNUNET_FS_SearchContext *parent, | 2481 | struct GNUNET_FS_SearchResult *psearch_result, |
2439 | const char *serialization) | 2482 | const char *serialization) |
2440 | { | 2483 | { |
2441 | struct GNUNET_FS_SearchContext *sc; | 2484 | struct GNUNET_FS_SearchContext *sc; |
2442 | struct GNUNET_FS_SearchContext *scc; | ||
2443 | struct GNUNET_BIO_ReadHandle *rhc; | ||
2444 | char *emsg; | 2485 | char *emsg; |
2445 | char *uris; | 2486 | char *uris; |
2446 | char *child_ser; | ||
2447 | char *dn; | 2487 | char *dn; |
2448 | uint32_t options; | 2488 | uint32_t options; |
2449 | char in_pause; | 2489 | char in_pause; |
2450 | 2490 | ||
2491 | if ( (psearch_result != NULL) && | ||
2492 | (psearch_result->update_search != NULL) ) | ||
2493 | { | ||
2494 | GNUNET_break (0); | ||
2495 | return NULL; | ||
2496 | } | ||
2451 | uris = NULL; | 2497 | uris = NULL; |
2452 | emsg = NULL; | 2498 | emsg = NULL; |
2453 | sc = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext)); | 2499 | sc = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext)); |
2454 | sc->parent = parent; | 2500 | if (psearch_result != NULL) |
2501 | { | ||
2502 | sc->psearch_result = psearch_result; | ||
2503 | psearch_result->update_search = sc; | ||
2504 | } | ||
2455 | sc->h = h; | 2505 | sc->h = h; |
2456 | sc->serialization = GNUNET_strdup (serialization); | 2506 | sc->serialization = GNUNET_strdup (serialization); |
2457 | if ( (GNUNET_OK != | 2507 | if ( (GNUNET_OK != |
@@ -2473,7 +2523,7 @@ deserialize_search (struct GNUNET_FS_Handle *h, | |||
2473 | sc->options = (enum GNUNET_FS_SearchOptions) options; | 2523 | sc->options = (enum GNUNET_FS_SearchOptions) options; |
2474 | sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); | 2524 | sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); |
2475 | dn = get_serialization_file_name_in_dir (h, | 2525 | dn = get_serialization_file_name_in_dir (h, |
2476 | (sc->parent == NULL) | 2526 | (sc->psearch_result == NULL) |
2477 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH | 2527 | ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH |
2478 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, | 2528 | : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, |
2479 | sc->serialization, | 2529 | sc->serialization, |
@@ -2490,42 +2540,7 @@ deserialize_search (struct GNUNET_FS_Handle *h, | |||
2490 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2540 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2491 | _("Could not resume running search, will resume as paused search\n")); | 2541 | _("Could not resume running search, will resume as paused search\n")); |
2492 | } | 2542 | } |
2493 | while (1) | ||
2494 | { | ||
2495 | if ( (GNUNET_OK != | ||
2496 | GNUNET_BIO_read_string (rh, "child-serialization", &child_ser, 32))) | ||
2497 | goto cleanup; | ||
2498 | if (child_ser == NULL) | ||
2499 | break; | ||
2500 | rhc = get_read_handle (h, GNUNET_FS_SYNC_PATH_CHILD_SEARCH, child_ser); | ||
2501 | if (rhc != NULL) | ||
2502 | { | ||
2503 | scc = deserialize_search (h, rhc, sc, child_ser); | ||
2504 | if (scc != NULL) | ||
2505 | GNUNET_CONTAINER_DLL_insert (sc->child_head, | ||
2506 | sc->child_tail, | ||
2507 | scc); | ||
2508 | emsg = NULL; | ||
2509 | if (GNUNET_OK != | ||
2510 | GNUNET_BIO_read_close (rhc, &emsg)) | ||
2511 | { | ||
2512 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2513 | _("Failed to resume sub-search `%s': %s\n"), | ||
2514 | child_ser, | ||
2515 | emsg); | ||
2516 | GNUNET_free (emsg); | ||
2517 | } | ||
2518 | } | ||
2519 | GNUNET_free (child_ser); | ||
2520 | } | ||
2521 | if (parent != NULL) | ||
2522 | GNUNET_CONTAINER_DLL_insert (parent->child_head, | ||
2523 | parent->child_tail, | ||
2524 | sc); | ||
2525 | signal_search_resume (sc); | 2543 | signal_search_resume (sc); |
2526 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, | ||
2527 | &signal_result_resume, | ||
2528 | sc); | ||
2529 | GNUNET_free (uris); | 2544 | GNUNET_free (uris); |
2530 | return sc; | 2545 | return sc; |
2531 | cleanup: | 2546 | cleanup: |
diff --git a/src/fs/fs.h b/src/fs/fs.h index f4f21faea..d7dcd987d 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -646,12 +646,16 @@ struct GNUNET_FS_SearchResult | |||
646 | /** | 646 | /** |
647 | * ID of an associated download based on this search result (or | 647 | * ID of an associated download based on this search result (or |
648 | * NULL for none). | 648 | * NULL for none). |
649 | * | ||
650 | * FIXME: not yet serialized. | ||
651 | */ | 649 | */ |
652 | struct GNUNET_FS_DownloadContext *download; | 650 | struct GNUNET_FS_DownloadContext *download; |
653 | 651 | ||
654 | /** | 652 | /** |
653 | * If this search result triggered an update search, this field | ||
654 | * links to the update search. | ||
655 | */ | ||
656 | struct GNUNET_FS_SearchContext *update_search; | ||
657 | |||
658 | /** | ||
655 | * Name under which this search result is stored on disk. | 659 | * Name under which this search result is stored on disk. |
656 | */ | 660 | */ |
657 | char *serialization; | 661 | char *serialization; |
@@ -1457,34 +1461,10 @@ struct GNUNET_FS_SearchContext | |||
1457 | struct GNUNET_FS_Uri *uri; | 1461 | struct GNUNET_FS_Uri *uri; |
1458 | 1462 | ||
1459 | /** | 1463 | /** |
1460 | * For update-searches, link to the base-SKS search that triggered | 1464 | * For update-searches, link to the search result that triggered |
1461 | * the update search; otherwise NULL. | ||
1462 | */ | ||
1463 | struct GNUNET_FS_SearchContext *parent; | ||
1464 | |||
1465 | /** | ||
1466 | * For update-searches, link to the first child search that | ||
1467 | * triggered the update search; otherwise NULL. | ||
1468 | */ | ||
1469 | struct GNUNET_FS_SearchContext *child_head; | ||
1470 | |||
1471 | /** | ||
1472 | * For update-searches, link to the last child search that triggered | ||
1473 | * the update search; otherwise NULL. | 1465 | * the update search; otherwise NULL. |
1474 | */ | 1466 | */ |
1475 | struct GNUNET_FS_SearchContext *child_tail; | 1467 | struct GNUNET_FS_SearchResult *psearch_result; |
1476 | |||
1477 | /** | ||
1478 | * For update-searches, link to the next child belonging to the same | ||
1479 | * parent. | ||
1480 | */ | ||
1481 | struct GNUNET_FS_SearchContext *next; | ||
1482 | |||
1483 | /** | ||
1484 | * For update-searches, link to the previous child belonging to the | ||
1485 | * same parent. | ||
1486 | */ | ||
1487 | struct GNUNET_FS_SearchContext *prev; | ||
1488 | 1468 | ||
1489 | /** | 1469 | /** |
1490 | * Connection to the FS service. | 1470 | * Connection to the FS service. |
@@ -1618,8 +1598,6 @@ struct GNUNET_FS_DownloadContext | |||
1618 | /** | 1598 | /** |
1619 | * Associated search (used when downloading files | 1599 | * Associated search (used when downloading files |
1620 | * based on search results), or NULL for none. | 1600 | * based on search results), or NULL for none. |
1621 | * | ||
1622 | * FIXME: not yet serialized | ||
1623 | */ | 1601 | */ |
1624 | struct GNUNET_FS_SearchResult *search; | 1602 | struct GNUNET_FS_SearchResult *search; |
1625 | 1603 | ||
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 8c324252f..9f62e04b1 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c | |||
@@ -53,7 +53,7 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi, | |||
53 | pi->value.search.cctx | 53 | pi->value.search.cctx |
54 | = sc->client_info; | 54 | = sc->client_info; |
55 | pi->value.search.pctx | 55 | pi->value.search.pctx |
56 | = (sc->parent == NULL) ? NULL : sc->parent->client_info; | 56 | = (sc->psearch_result == NULL) ? NULL : sc->psearch_result->client_info; |
57 | pi->value.search.query | 57 | pi->value.search.query |
58 | = sc->uri; | 58 | = sc->uri; |
59 | pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time); | 59 | pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time); |
@@ -462,7 +462,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc, | |||
462 | * @param anonymity desired level of anonymity | 462 | * @param anonymity desired level of anonymity |
463 | * @param options options for the search | 463 | * @param options options for the search |
464 | * @param cctx client context | 464 | * @param cctx client context |
465 | * @param parent parent search (for namespace update searches) | 465 | * @param psearch parent search result (for namespace update searches) |
466 | * @return context that can be used to control the search | 466 | * @return context that can be used to control the search |
467 | */ | 467 | */ |
468 | static struct GNUNET_FS_SearchContext * | 468 | static struct GNUNET_FS_SearchContext * |
@@ -471,7 +471,7 @@ search_start (struct GNUNET_FS_Handle *h, | |||
471 | uint32_t anonymity, | 471 | uint32_t anonymity, |
472 | enum GNUNET_FS_SearchOptions options, | 472 | enum GNUNET_FS_SearchOptions options, |
473 | void *cctx, | 473 | void *cctx, |
474 | struct GNUNET_FS_SearchContext *parent); | 474 | struct GNUNET_FS_SearchResult *psearch); |
475 | 475 | ||
476 | 476 | ||
477 | /** | 477 | /** |
@@ -523,14 +523,12 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, | |||
523 | uu.type = sks; | 523 | uu.type = sks; |
524 | uu.data.sks.namespace = sc->uri->data.sks.namespace; | 524 | uu.data.sks.namespace = sc->uri->data.sks.namespace; |
525 | uu.data.sks.identifier = GNUNET_strdup (id_update); | 525 | uu.data.sks.identifier = GNUNET_strdup (id_update); |
526 | /* FIXME: should attach update search to the individual result, not | 526 | (void) search_start (sc->h, |
527 | the entire SKS search! */ | 527 | &uu, |
528 | search_start (sc->h, | 528 | sc->anonymity, |
529 | &uu, | 529 | sc->options, |
530 | sc->anonymity, | 530 | NULL, |
531 | sc->options, | 531 | sr); |
532 | NULL, | ||
533 | sc); | ||
534 | } | 532 | } |
535 | 533 | ||
536 | 534 | ||
@@ -1064,7 +1062,7 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc) | |||
1064 | * @param anonymity desired level of anonymity | 1062 | * @param anonymity desired level of anonymity |
1065 | * @param options options for the search | 1063 | * @param options options for the search |
1066 | * @param cctx initial value for the client context | 1064 | * @param cctx initial value for the client context |
1067 | * @param parent parent search (for namespace update searches) | 1065 | * @param psearch parent search result (for namespace update searches) |
1068 | * @return context that can be used to control the search | 1066 | * @return context that can be used to control the search |
1069 | */ | 1067 | */ |
1070 | static struct GNUNET_FS_SearchContext * | 1068 | static struct GNUNET_FS_SearchContext * |
@@ -1073,7 +1071,7 @@ search_start (struct GNUNET_FS_Handle *h, | |||
1073 | uint32_t anonymity, | 1071 | uint32_t anonymity, |
1074 | enum GNUNET_FS_SearchOptions options, | 1072 | enum GNUNET_FS_SearchOptions options, |
1075 | void *cctx, | 1073 | void *cctx, |
1076 | struct GNUNET_FS_SearchContext *parent) | 1074 | struct GNUNET_FS_SearchResult *psearch) |
1077 | { | 1075 | { |
1078 | struct GNUNET_FS_SearchContext *sc; | 1076 | struct GNUNET_FS_SearchContext *sc; |
1079 | struct GNUNET_FS_ProgressInfo pi; | 1077 | struct GNUNET_FS_ProgressInfo pi; |
@@ -1084,13 +1082,13 @@ search_start (struct GNUNET_FS_Handle *h, | |||
1084 | sc->uri = GNUNET_FS_uri_dup (uri); | 1082 | sc->uri = GNUNET_FS_uri_dup (uri); |
1085 | sc->anonymity = anonymity; | 1083 | sc->anonymity = anonymity; |
1086 | sc->start_time = GNUNET_TIME_absolute_get (); | 1084 | sc->start_time = GNUNET_TIME_absolute_get (); |
1087 | sc->parent = parent; | 1085 | if (psearch != NULL) |
1086 | { | ||
1087 | sc->psearch_result = psearch; | ||
1088 | psearch->update_search = sc; | ||
1089 | } | ||
1088 | sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); | 1090 | sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); |
1089 | sc->client_info = cctx; | 1091 | sc->client_info = cctx; |
1090 | if (NULL != parent) | ||
1091 | GNUNET_CONTAINER_DLL_insert (parent->child_head, | ||
1092 | parent->child_tail, | ||
1093 | sc); | ||
1094 | if (GNUNET_OK != | 1092 | if (GNUNET_OK != |
1095 | GNUNET_FS_search_start_searching_ (sc)) | 1093 | GNUNET_FS_search_start_searching_ (sc)) |
1096 | { | 1094 | { |
@@ -1206,6 +1204,8 @@ search_result_freeze_probes (void *cls, | |||
1206 | sr->probe_cancel_task); | 1204 | sr->probe_cancel_task); |
1207 | sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; | 1205 | sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; |
1208 | } | 1206 | } |
1207 | if (sr->update_search != NULL) | ||
1208 | GNUNET_FS_search_pause (sr->update_search); | ||
1209 | return GNUNET_OK; | 1209 | return GNUNET_OK; |
1210 | } | 1210 | } |
1211 | 1211 | ||
@@ -1226,11 +1226,23 @@ search_result_resume_probes (void *cls, | |||
1226 | struct GNUNET_FS_SearchResult *sr = value; | 1226 | struct GNUNET_FS_SearchResult *sr = value; |
1227 | 1227 | ||
1228 | GNUNET_FS_search_start_probe_ (sr); | 1228 | GNUNET_FS_search_start_probe_ (sr); |
1229 | if (sr->update_search != NULL) | ||
1230 | GNUNET_FS_search_continue (sr->update_search); | ||
1229 | return GNUNET_OK; | 1231 | return GNUNET_OK; |
1230 | } | 1232 | } |
1231 | 1233 | ||
1232 | 1234 | ||
1233 | /** | 1235 | /** |
1236 | * Create SUSPEND event for the given search operation | ||
1237 | * and then clean up our state (without stop signal). | ||
1238 | * | ||
1239 | * @param cls the 'struct GNUNET_FS_SearchContext' to signal for | ||
1240 | */ | ||
1241 | static void | ||
1242 | search_signal_suspend (void *cls); | ||
1243 | |||
1244 | |||
1245 | /** | ||
1234 | * Signal suspend and free the given search result. | 1246 | * Signal suspend and free the given search result. |
1235 | * | 1247 | * |
1236 | * @param cls the global FS handle | 1248 | * @param cls the global FS handle |
@@ -1250,6 +1262,8 @@ search_result_suspend (void *cls, | |||
1250 | 1262 | ||
1251 | if (sr->download != NULL) | 1263 | if (sr->download != NULL) |
1252 | GNUNET_FS_download_signal_suspend_ (sr->download); | 1264 | GNUNET_FS_download_signal_suspend_ (sr->download); |
1265 | if (sr->update_search != NULL) | ||
1266 | search_signal_suspend (sr->update_search); | ||
1253 | pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND; | 1267 | pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND; |
1254 | pi.value.search.specifics.result_suspend.cctx = sr->client_info; | 1268 | pi.value.search.specifics.result_suspend.cctx = sr->client_info; |
1255 | pi.value.search.specifics.result_suspend.meta = sr->meta; | 1269 | pi.value.search.specifics.result_suspend.meta = sr->meta; |
@@ -1279,20 +1293,10 @@ static void | |||
1279 | search_signal_suspend (void *cls) | 1293 | search_signal_suspend (void *cls) |
1280 | { | 1294 | { |
1281 | struct GNUNET_FS_SearchContext *sc = cls; | 1295 | struct GNUNET_FS_SearchContext *sc = cls; |
1282 | struct GNUNET_FS_SearchContext *parent = cls; | ||
1283 | struct GNUNET_FS_ProgressInfo pi; | 1296 | struct GNUNET_FS_ProgressInfo pi; |
1284 | unsigned int i; | 1297 | unsigned int i; |
1285 | 1298 | ||
1286 | GNUNET_FS_end_top (sc->h, sc->top); | 1299 | GNUNET_FS_end_top (sc->h, sc->top); |
1287 | if (NULL != (parent = sc->parent)) | ||
1288 | { | ||
1289 | GNUNET_CONTAINER_DLL_remove (parent->child_head, | ||
1290 | parent->child_tail, | ||
1291 | sc); | ||
1292 | sc->parent = NULL; | ||
1293 | } | ||
1294 | while (NULL != sc->child_head) | ||
1295 | search_signal_suspend (sc->child_head); | ||
1296 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, | 1300 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, |
1297 | &search_result_suspend, | 1301 | &search_result_suspend, |
1298 | sc); | 1302 | sc); |
@@ -1426,6 +1430,11 @@ search_result_free (void *cls, | |||
1426 | GNUNET_FS_download_sync_ (sr->download); | 1430 | GNUNET_FS_download_sync_ (sr->download); |
1427 | sr->download = NULL; | 1431 | sr->download = NULL; |
1428 | } | 1432 | } |
1433 | if (NULL != sr->update_search) | ||
1434 | { | ||
1435 | GNUNET_FS_search_stop (sr->update_search); | ||
1436 | GNUNET_assert (sr->update_search == NULL); | ||
1437 | } | ||
1429 | pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; | 1438 | pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; |
1430 | pi.value.search.specifics.result_stopped.cctx = sr->client_info; | 1439 | pi.value.search.specifics.result_stopped.cctx = sr->client_info; |
1431 | pi.value.search.specifics.result_stopped.meta = sr->meta; | 1440 | pi.value.search.specifics.result_stopped.meta = sr->meta; |
@@ -1455,31 +1464,23 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) | |||
1455 | { | 1464 | { |
1456 | struct GNUNET_FS_ProgressInfo pi; | 1465 | struct GNUNET_FS_ProgressInfo pi; |
1457 | unsigned int i; | 1466 | unsigned int i; |
1458 | struct GNUNET_FS_SearchContext *parent; | ||
1459 | 1467 | ||
1460 | if (sc->top != NULL) | 1468 | if (sc->top != NULL) |
1461 | GNUNET_FS_end_top (sc->h, sc->top); | 1469 | GNUNET_FS_end_top (sc->h, sc->top); |
1462 | if (NULL != (parent = sc->parent)) | 1470 | if (sc->psearch_result != NULL) |
1463 | { | 1471 | sc->psearch_result->update_search = NULL; |
1464 | GNUNET_CONTAINER_DLL_remove (parent->child_head, | ||
1465 | parent->child_tail, | ||
1466 | sc); | ||
1467 | sc->parent = NULL; | ||
1468 | } | ||
1469 | while (NULL != sc->child_head) | ||
1470 | GNUNET_FS_search_stop (sc->child_head); | ||
1471 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, | 1472 | GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, |
1472 | &search_result_free, | 1473 | &search_result_free, |
1473 | sc); | 1474 | sc); |
1474 | if (sc->serialization != NULL) | 1475 | if (sc->serialization != NULL) |
1475 | { | 1476 | { |
1476 | GNUNET_FS_remove_sync_file_ (sc->h, | 1477 | GNUNET_FS_remove_sync_file_ (sc->h, |
1477 | (sc->parent != NULL) | 1478 | (sc->psearch_result != NULL) |
1478 | ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH | 1479 | ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH |
1479 | : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, | 1480 | : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, |
1480 | sc->serialization); | 1481 | sc->serialization); |
1481 | GNUNET_FS_remove_sync_dir_ (sc->h, | 1482 | GNUNET_FS_remove_sync_dir_ (sc->h, |
1482 | (sc->parent != NULL) | 1483 | (sc->psearch_result != NULL) |
1483 | ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH | 1484 | ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH |
1484 | : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, | 1485 | : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, |
1485 | sc->serialization); | 1486 | sc->serialization); |
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 2207e274e..d40ae4ef7 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h | |||
@@ -21,10 +21,6 @@ | |||
21 | * @file include/gnunet_fs_service.h | 21 | * @file include/gnunet_fs_service.h |
22 | * @brief API for file-sharing via GNUnet | 22 | * @brief API for file-sharing via GNUnet |
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * | ||
25 | * TODO: | ||
26 | * - extend API with support for publish simulation (-s) | ||
27 | * and URI-argument binding to keyword/namespace (-u) | ||
28 | */ | 24 | */ |
29 | #ifndef GNUNET_FS_LIB_H | 25 | #ifndef GNUNET_FS_LIB_H |
30 | #define GNUNET_FS_LIB_H | 26 | #define GNUNET_FS_LIB_H |
@@ -1078,8 +1074,10 @@ struct GNUNET_FS_ProgressInfo | |||
1078 | 1074 | ||
1079 | /** | 1075 | /** |
1080 | * Client parent-context pointer; NULL for top-level searches, | 1076 | * Client parent-context pointer; NULL for top-level searches, |
1081 | * non-NULL for automatically triggered searches for updates in | 1077 | * refers to the client context of the associated search result |
1082 | * namespaces. | 1078 | * for automatically triggered searches for updates in |
1079 | * namespaces. In this case, 'presult' refers to that search | ||
1080 | * result. | ||
1083 | */ | 1081 | */ |
1084 | void *pctx; | 1082 | void *pctx; |
1085 | 1083 | ||