diff options
-rw-r--r-- | TODO | 13 | ||||
-rw-r--r-- | src/fs/fs.c | 136 | ||||
-rw-r--r-- | src/fs/fs.h | 54 | ||||
-rw-r--r-- | src/fs/fs_download.c | 114 | ||||
-rw-r--r-- | src/fs/fs_search.c | 15 | ||||
-rw-r--r-- | src/fs/fs_test_lib.c | 3 | ||||
-rw-r--r-- | src/fs/gnunet-download.c | 3 | ||||
-rw-r--r-- | src/include/gnunet_fs_service.h | 10 |
8 files changed, 233 insertions, 115 deletions
@@ -1,8 +1,9 @@ | |||
1 | 0.9.0pre1: | 1 | 0.9.0pre1: |
2 | * FS: [CG] | 2 | * FS: [CG] |
3 | - bound parallelism (# fs downloads) | 3 | - search: availability probes [needed for full persistence support...] |
4 | - distinguish in performance tracking and event signalling between | 4 | - Allow checking of presence of search results and/or content via command-line tools |
5 | downloads that are actually running and those that are merely in the queue | 5 | (add options to gnunet-search / gnunet-download to limit search to local peer) |
6 | [needed for full persistence support...] | ||
6 | - persistence support (publish, unindex, search, download) | 7 | - persistence support (publish, unindex, search, download) |
7 | - gnunet-service-fs (hot-path routing, load-based routing, nitpicks) | 8 | - gnunet-service-fs (hot-path routing, load-based routing, nitpicks) |
8 | - [gnunet-service-fs.c:208]: member 'LocalGetContext::results_bf_size' is never used | 9 | - [gnunet-service-fs.c:208]: member 'LocalGetContext::results_bf_size' is never used |
@@ -70,7 +71,6 @@ | |||
70 | - shutdown sequence? | 71 | - shutdown sequence? |
71 | * FS: [CG] | 72 | * FS: [CG] |
72 | - datastore reservation (publishing) | 73 | - datastore reservation (publishing) |
73 | - search: availability probes | ||
74 | - location URIs (publish, search, download) | 74 | - location URIs (publish, search, download) |
75 | - non-anonymous FS service (needs DHT) | 75 | - non-anonymous FS service (needs DHT) |
76 | + DHT integration for search | 76 | + DHT integration for search |
@@ -116,8 +116,7 @@ | |||
116 | - convert documentation pages to books | 116 | - convert documentation pages to books |
117 | - update books (especially for developers) | 117 | - update books (especially for developers) |
118 | - create good Drupal theme for GNUnet | 118 | - create good Drupal theme for GNUnet |
119 | - make a NICE download page and figure out how to | 119 | - make a NICE download page and figure out how to enable developers to publish TGZs nicely |
120 | enable developers to publish TGZs nicely | ||
121 | - port "contact" page | 120 | - port "contact" page |
122 | - add content type for "todo" items? | 121 | - add content type for "todo" items? |
123 | * POSTGRES database backends: [CG] | 122 | * POSTGRES database backends: [CG] |
@@ -151,8 +150,6 @@ | |||
151 | (Note: build library always, build service when libxml2/etc. are available) | 150 | (Note: build library always, build service when libxml2/etc. are available) |
152 | * FS: [CG] | 151 | * FS: [CG] |
153 | - Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009) | 152 | - Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009) |
154 | - Allow checking of presence of search results and/or content via command-line tools | ||
155 | (add options to gnunet-search / gnunet-download to limit search to local peer) | ||
156 | * PEERINFO: [CG] | 153 | * PEERINFO: [CG] |
157 | - expire 'ancient' HELLOs (those without valid addresses AND that | 154 | - expire 'ancient' HELLOs (those without valid addresses AND that |
158 | we have not 'used' (for their public keys) in a while; need a way | 155 | we have not 'used' (for their public keys) in a while; need a way |
diff --git a/src/fs/fs.c b/src/fs/fs.c index 2888abe93..6dbc182b7 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -45,20 +45,13 @@ start_job (struct GNUNET_FS_QueueEntry *qe) | |||
45 | return; | 45 | return; |
46 | } | 46 | } |
47 | qe->start (qe->cls, qe->client); | 47 | qe->start (qe->cls, qe->client); |
48 | switch (qe->category) | 48 | qe->start_times++; |
49 | { | 49 | qe->h->active_blocks += qe->blocks; |
50 | case GNUNET_FS_QC_DOWNLOAD: | ||
51 | qe->h->active_downloads++; | ||
52 | break; | ||
53 | case GNUNET_FS_QC_PROBE: | ||
54 | qe->h->active_probes++; | ||
55 | break; | ||
56 | } | ||
57 | qe->start_time = GNUNET_TIME_absolute_get (); | 50 | qe->start_time = GNUNET_TIME_absolute_get (); |
58 | GNUNET_CONTAINER_DLL_remove (qe->h->pending_head, | 51 | GNUNET_CONTAINER_DLL_remove (qe->h->pending_head, |
59 | qe->h->pending_tail, | 52 | qe->h->pending_tail, |
60 | qe); | 53 | qe); |
61 | GNUNET_CONTAINER_DLL_insert_after (qe->h->pending_head, | 54 | GNUNET_CONTAINER_DLL_insert_after (qe->h->running_head, |
62 | qe->h->running_tail, | 55 | qe->h->running_tail, |
63 | qe->h->running_tail, | 56 | qe->h->running_tail, |
64 | qe); | 57 | qe); |
@@ -76,15 +69,8 @@ stop_job (struct GNUNET_FS_QueueEntry *qe) | |||
76 | { | 69 | { |
77 | qe->client = NULL; | 70 | qe->client = NULL; |
78 | qe->stop (qe->cls); | 71 | qe->stop (qe->cls); |
79 | switch (qe->category) | 72 | qe->h->active_downloads--; |
80 | { | 73 | qe->h->active_blocks -= qe->blocks; |
81 | case GNUNET_FS_QC_DOWNLOAD: | ||
82 | qe->h->active_downloads--; | ||
83 | break; | ||
84 | case GNUNET_FS_QC_PROBE: | ||
85 | qe->h->active_probes--; | ||
86 | break; | ||
87 | } | ||
88 | qe->run_time = GNUNET_TIME_relative_add (qe->run_time, | 74 | qe->run_time = GNUNET_TIME_relative_add (qe->run_time, |
89 | GNUNET_TIME_absolute_get_duration (qe->start_time)); | 75 | GNUNET_TIME_absolute_get_duration (qe->start_time)); |
90 | GNUNET_CONTAINER_DLL_remove (qe->h->running_head, | 76 | GNUNET_CONTAINER_DLL_remove (qe->h->running_head, |
@@ -109,13 +95,54 @@ process_job_queue (void *cls, | |||
109 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 95 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
110 | { | 96 | { |
111 | struct GNUNET_FS_Handle *h = cls; | 97 | struct GNUNET_FS_Handle *h = cls; |
98 | struct GNUNET_FS_QueueEntry *qe; | ||
99 | struct GNUNET_FS_QueueEntry *next; | ||
100 | struct GNUNET_TIME_Relative run_time; | ||
101 | struct GNUNET_TIME_Relative restart_at; | ||
102 | struct GNUNET_TIME_Relative rst; | ||
103 | struct GNUNET_TIME_Absolute end_time; | ||
112 | 104 | ||
113 | h->queue_job = GNUNET_SCHEDULER_NO_TASK; | 105 | h->queue_job = GNUNET_SCHEDULER_NO_TASK; |
114 | /* FIXME: stupid implementation that just starts everything follows... */ | 106 | next = h->pending_head; |
115 | while (NULL != h->pending_head) | 107 | while (NULL != (qe = next)) |
116 | start_job (h->pending_head); | 108 | { |
117 | 109 | next = qe->next; | |
118 | /* FIXME: possibly re-schedule queue-job! */ | 110 | if (h->running_head == NULL) |
111 | { | ||
112 | start_job (qe); | ||
113 | continue; | ||
114 | } | ||
115 | if ( (qe->blocks + h->active_blocks <= h->max_parallel_requests) && | ||
116 | (h->active_downloads + 1 <= h->max_parallel_downloads) ) | ||
117 | { | ||
118 | start_job (qe); | ||
119 | continue; | ||
120 | } | ||
121 | } | ||
122 | if (h->pending_head == NULL) | ||
123 | return; /* no need to stop anything */ | ||
124 | restart_at = GNUNET_TIME_UNIT_FOREVER_REL; | ||
125 | next = h->running_head; | ||
126 | while (NULL != (qe = next)) | ||
127 | { | ||
128 | next = qe->next; | ||
129 | /* FIXME: might be faster/simpler to do this calculation only once | ||
130 | when we start a job (OTOH, this would allow us to dynamically | ||
131 | and easily adjust qe->blocks over time, given the right API...) */ | ||
132 | run_time = GNUNET_TIME_relative_multiply (h->avg_block_latency, | ||
133 | qe->blocks * qe->start_times); | ||
134 | end_time = GNUNET_TIME_absolute_add (qe->start_time, | ||
135 | run_time); | ||
136 | rst = GNUNET_TIME_absolute_get_remaining (end_time); | ||
137 | restart_at = GNUNET_TIME_relative_min (rst, restart_at); | ||
138 | if (rst.value > 0) | ||
139 | continue; | ||
140 | stop_job (qe); | ||
141 | } | ||
142 | h->queue_job = GNUNET_SCHEDULER_add_delayed (h->sched, | ||
143 | restart_at, | ||
144 | &process_job_queue, | ||
145 | h); | ||
119 | } | 146 | } |
120 | 147 | ||
121 | /** | 148 | /** |
@@ -125,7 +152,7 @@ process_job_queue (void *cls, | |||
125 | * @param start function to call to begin the job | 152 | * @param start function to call to begin the job |
126 | * @param stop function to call to pause the job, or on dequeue (if the job was running) | 153 | * @param stop function to call to pause the job, or on dequeue (if the job was running) |
127 | * @param cls closure for start and stop | 154 | * @param cls closure for start and stop |
128 | * @param cat category of the job | 155 | * @param blocks number of blocks this jobs uses |
129 | * @return queue handle | 156 | * @return queue handle |
130 | */ | 157 | */ |
131 | struct GNUNET_FS_QueueEntry * | 158 | struct GNUNET_FS_QueueEntry * |
@@ -133,7 +160,7 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, | |||
133 | GNUNET_FS_QueueStart start, | 160 | GNUNET_FS_QueueStart start, |
134 | GNUNET_FS_QueueStop stop, | 161 | GNUNET_FS_QueueStop stop, |
135 | void *cls, | 162 | void *cls, |
136 | enum GNUNET_FS_QueueCategory cat) | 163 | unsigned int blocks) |
137 | { | 164 | { |
138 | struct GNUNET_FS_QueueEntry *qe; | 165 | struct GNUNET_FS_QueueEntry *qe; |
139 | 166 | ||
@@ -143,7 +170,7 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, | |||
143 | qe->stop = stop; | 170 | qe->stop = stop; |
144 | qe->cls = cls; | 171 | qe->cls = cls; |
145 | qe->queue_time = GNUNET_TIME_absolute_get (); | 172 | qe->queue_time = GNUNET_TIME_absolute_get (); |
146 | qe->category = cat; | 173 | qe->blocks = blocks; |
147 | GNUNET_CONTAINER_DLL_insert_after (h->pending_head, | 174 | GNUNET_CONTAINER_DLL_insert_after (h->pending_head, |
148 | h->pending_tail, | 175 | h->pending_tail, |
149 | h->pending_tail, | 176 | h->pending_tail, |
@@ -166,21 +193,22 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, | |||
166 | void | 193 | void |
167 | GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) | 194 | GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) |
168 | { | 195 | { |
196 | struct GNUNET_FS_Handle *h; | ||
197 | |||
198 | h = qh->h; | ||
169 | if (qh->client != NULL) | 199 | if (qh->client != NULL) |
170 | { | 200 | stop_job (qh); |
171 | if (qh->h->queue_job != GNUNET_SCHEDULER_NO_TASK) | 201 | GNUNET_CONTAINER_DLL_remove (h->pending_head, |
172 | GNUNET_SCHEDULER_cancel (qh->h->sched, | 202 | h->pending_tail, |
173 | qh->h->queue_job); | ||
174 | qh->h->queue_job | ||
175 | = GNUNET_SCHEDULER_add_now (qh->h->sched, | ||
176 | &process_job_queue, | ||
177 | qh->h); | ||
178 | stop_job (qh); | ||
179 | } | ||
180 | GNUNET_CONTAINER_DLL_remove (qh->h->pending_head, | ||
181 | qh->h->pending_tail, | ||
182 | qh); | 203 | qh); |
183 | GNUNET_free (qh); | 204 | GNUNET_free (qh); |
205 | if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) | ||
206 | GNUNET_SCHEDULER_cancel (h->sched, | ||
207 | h->queue_job); | ||
208 | h->queue_job | ||
209 | = GNUNET_SCHEDULER_add_now (h->sched, | ||
210 | &process_job_queue, | ||
211 | h); | ||
184 | } | 212 | } |
185 | 213 | ||
186 | 214 | ||
@@ -207,7 +235,9 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
207 | { | 235 | { |
208 | struct GNUNET_FS_Handle *ret; | 236 | struct GNUNET_FS_Handle *ret; |
209 | struct GNUNET_CLIENT_Connection *client; | 237 | struct GNUNET_CLIENT_Connection *client; |
210 | 238 | enum GNUNET_FS_OPTIONS opt; | |
239 | va_list ap; | ||
240 | |||
211 | client = GNUNET_CLIENT_connect (sched, | 241 | client = GNUNET_CLIENT_connect (sched, |
212 | "fs", | 242 | "fs", |
213 | cfg); | 243 | cfg); |
@@ -221,7 +251,29 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
221 | ret->upcb_cls = upcb_cls; | 251 | ret->upcb_cls = upcb_cls; |
222 | ret->client = client; | 252 | ret->client = client; |
223 | ret->flags = flags; | 253 | ret->flags = flags; |
224 | // FIXME: process varargs! | 254 | ret->max_parallel_downloads = 1; |
255 | ret->max_parallel_requests = 1; | ||
256 | ret->avg_block_latency = GNUNET_TIME_UNIT_MINUTES; /* conservative starting point */ | ||
257 | va_start (ap, flags); | ||
258 | while (GNUNET_FS_OPTIONS_END != (opt = va_arg (ap, enum GNUNET_FS_OPTIONS))) | ||
259 | { | ||
260 | switch (opt) | ||
261 | { | ||
262 | case GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM: | ||
263 | ret->max_parallel_downloads = va_arg (ap, unsigned int); | ||
264 | break; | ||
265 | case GNUNET_FS_OPTIONS_REQUEST_PARALLELISM: | ||
266 | ret->max_parallel_requests = va_arg (ap, unsigned int); | ||
267 | break; | ||
268 | default: | ||
269 | GNUNET_break (0); | ||
270 | GNUNET_free (ret->client_name); | ||
271 | GNUNET_free (ret); | ||
272 | va_end (ap); | ||
273 | return NULL; | ||
274 | } | ||
275 | } | ||
276 | va_end (ap); | ||
225 | // FIXME: setup receive-loop with client | 277 | // FIXME: setup receive-loop with client |
226 | 278 | ||
227 | // FIXME: deserialize state; use client-name to find master-directory! | 279 | // FIXME: deserialize state; use client-name to find master-directory! |
diff --git a/src/fs/fs.h b/src/fs/fs.h index b10add77c..e11b0aa74 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -462,22 +462,6 @@ typedef void (*GNUNET_FS_QueueStart)(void *cls, | |||
462 | */ | 462 | */ |
463 | typedef void (*GNUNET_FS_QueueStop)(void *cls); | 463 | typedef void (*GNUNET_FS_QueueStop)(void *cls); |
464 | 464 | ||
465 | /** | ||
466 | * Categories of jobs in the FS queue. | ||
467 | */ | ||
468 | enum GNUNET_FS_QueueCategory | ||
469 | { | ||
470 | /** | ||
471 | * File download. | ||
472 | */ | ||
473 | GNUNET_FS_QC_DOWNLOAD, | ||
474 | |||
475 | /** | ||
476 | * Availability probe (related to search). | ||
477 | */ | ||
478 | GNUNET_FS_QC_PROBE | ||
479 | |||
480 | }; | ||
481 | 465 | ||
482 | /** | 466 | /** |
483 | * Entry in the job queue. | 467 | * Entry in the job queue. |
@@ -536,9 +520,14 @@ struct GNUNET_FS_QueueEntry | |||
536 | struct GNUNET_TIME_Relative run_time; | 520 | struct GNUNET_TIME_Relative run_time; |
537 | 521 | ||
538 | /** | 522 | /** |
539 | * What type of job is this? | 523 | * How many blocks do the active downloads have? |
524 | */ | ||
525 | unsigned int blocks; | ||
526 | |||
527 | /** | ||
528 | * How often have we (re)started this download? | ||
540 | */ | 529 | */ |
541 | enum GNUNET_FS_QueueCategory category; | 530 | unsigned int start_times; |
542 | 531 | ||
543 | }; | 532 | }; |
544 | 533 | ||
@@ -552,6 +541,7 @@ struct GNUNET_FS_QueueEntry | |||
552 | * @param start function to call to begin the job | 541 | * @param start function to call to begin the job |
553 | * @param stop function to call to pause the job, or on dequeue (if the job was running) | 542 | * @param stop function to call to pause the job, or on dequeue (if the job was running) |
554 | * @param cls closure for start and stop | 543 | * @param cls closure for start and stop |
544 | * @param blocks number of blocks this download has | ||
555 | * @return queue handle | 545 | * @return queue handle |
556 | */ | 546 | */ |
557 | struct GNUNET_FS_QueueEntry * | 547 | struct GNUNET_FS_QueueEntry * |
@@ -559,7 +549,7 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, | |||
559 | GNUNET_FS_QueueStart start, | 549 | GNUNET_FS_QueueStart start, |
560 | GNUNET_FS_QueueStop stop, | 550 | GNUNET_FS_QueueStop stop, |
561 | void *cls, | 551 | void *cls, |
562 | enum GNUNET_FS_QueueCategory cat); | 552 | unsigned int blocks); |
563 | 553 | ||
564 | 554 | ||
565 | /** | 555 | /** |
@@ -632,10 +622,10 @@ struct GNUNET_FS_Handle | |||
632 | GNUNET_SCHEDULER_TaskIdentifier queue_job; | 622 | GNUNET_SCHEDULER_TaskIdentifier queue_job; |
633 | 623 | ||
634 | /** | 624 | /** |
635 | * How many downloads probing availability of search results do we | 625 | * Average time we take for a single request to be satisfied. |
636 | * have running right now? | 626 | * FIXME: not yet calcualted properly... |
637 | */ | 627 | */ |
638 | unsigned int active_probes; | 628 | struct GNUNET_TIME_Relative avg_block_latency; |
639 | 629 | ||
640 | /** | 630 | /** |
641 | * How many actual downloads do we have running right now? | 631 | * How many actual downloads do we have running right now? |
@@ -643,10 +633,25 @@ struct GNUNET_FS_Handle | |||
643 | unsigned int active_downloads; | 633 | unsigned int active_downloads; |
644 | 634 | ||
645 | /** | 635 | /** |
636 | * How many blocks do the active downloads have? | ||
637 | */ | ||
638 | unsigned int active_blocks; | ||
639 | |||
640 | /** | ||
646 | * General flags. | 641 | * General flags. |
647 | */ | 642 | */ |
648 | enum GNUNET_FS_Flags flags; | 643 | enum GNUNET_FS_Flags flags; |
649 | 644 | ||
645 | /** | ||
646 | * Maximum number of parallel downloads. | ||
647 | */ | ||
648 | unsigned int max_parallel_downloads; | ||
649 | |||
650 | /** | ||
651 | * Maximum number of parallel requests. | ||
652 | */ | ||
653 | unsigned int max_parallel_requests; | ||
654 | |||
650 | }; | 655 | }; |
651 | 656 | ||
652 | 657 | ||
@@ -1189,6 +1194,11 @@ struct GNUNET_FS_DownloadContext | |||
1189 | struct GNUNET_CLIENT_TransmitHandle *th; | 1194 | struct GNUNET_CLIENT_TransmitHandle *th; |
1190 | 1195 | ||
1191 | /** | 1196 | /** |
1197 | * Our entry in the job queue. | ||
1198 | */ | ||
1199 | struct GNUNET_FS_QueueEntry *job_queue; | ||
1200 | |||
1201 | /** | ||
1192 | * Identity of the peer having the content, or all-zeros | 1202 | * Identity of the peer having the content, or all-zeros |
1193 | * if we don't know of such a peer. | 1203 | * if we don't know of such a peer. |
1194 | */ | 1204 | */ |
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 1f03082e8..424aaf5d4 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -23,12 +23,9 @@ | |||
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * | 24 | * |
25 | * TODO: | 25 | * TODO: |
26 | * - handle recursive downloads (need directory & | ||
27 | * fs-level download-parallelism management) | ||
28 | * - location URI suppport (can wait, easy) | 26 | * - location URI suppport (can wait, easy) |
29 | * - check if blocks exist already (can wait, easy) | ||
30 | * - check if iblocks can be computed from existing blocks (can wait, hard) | ||
31 | * - persistence (can wait) | 27 | * - persistence (can wait) |
28 | * - check if iblocks can be computed from existing blocks (can wait, hard) | ||
32 | */ | 29 | */ |
33 | #include "platform.h" | 30 | #include "platform.h" |
34 | #include "gnunet_constants.h" | 31 | #include "gnunet_constants.h" |
@@ -990,7 +987,11 @@ process_result_with_request (void *cls, | |||
990 | "truncate", | 987 | "truncate", |
991 | dc->filename); | 988 | dc->filename); |
992 | } | 989 | } |
993 | 990 | if (dc->job_queue != NULL) | |
991 | { | ||
992 | GNUNET_FS_dequeue_ (dc->job_queue); | ||
993 | dc->job_queue = NULL; | ||
994 | } | ||
994 | if (is_recursive_download (dc)) | 995 | if (is_recursive_download (dc)) |
995 | full_recursive_download (dc); | 996 | full_recursive_download (dc); |
996 | if (dc->child_head == NULL) | 997 | if (dc->child_head == NULL) |
@@ -1273,6 +1274,73 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) | |||
1273 | } | 1274 | } |
1274 | 1275 | ||
1275 | 1276 | ||
1277 | |||
1278 | /** | ||
1279 | * We're allowed to ask the FS service for our blocks. Start the download. | ||
1280 | * | ||
1281 | * @param cls the 'struct GNUNET_FS_DownloadContext' | ||
1282 | * @param client handle to use for communcation with FS (we must destroy it!) | ||
1283 | */ | ||
1284 | static void | ||
1285 | activate_fs_download (void *cls, | ||
1286 | struct GNUNET_CLIENT_Connection *client) | ||
1287 | { | ||
1288 | struct GNUNET_FS_DownloadContext *dc = cls; | ||
1289 | struct GNUNET_FS_ProgressInfo pi; | ||
1290 | |||
1291 | GNUNET_assert (NULL != client); | ||
1292 | dc->client = client; | ||
1293 | GNUNET_CLIENT_receive (client, | ||
1294 | &receive_results, | ||
1295 | dc, | ||
1296 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1297 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; | ||
1298 | make_download_status (&pi, dc); | ||
1299 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, | ||
1300 | &pi); | ||
1301 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, | ||
1302 | &retry_entry, | ||
1303 | dc); | ||
1304 | if ( (dc->th == NULL) && | ||
1305 | (dc->client != NULL) ) | ||
1306 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | ||
1307 | sizeof (struct SearchMessage), | ||
1308 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
1309 | GNUNET_NO, | ||
1310 | &transmit_download_request, | ||
1311 | dc); | ||
1312 | } | ||
1313 | |||
1314 | |||
1315 | /** | ||
1316 | * We must stop to ask the FS service for our blocks. Pause the download. | ||
1317 | * | ||
1318 | * @param cls the 'struct GNUNET_FS_DownloadContext' | ||
1319 | * @param client handle to use for communcation with FS (we must destroy it!) | ||
1320 | */ | ||
1321 | static void | ||
1322 | deactivate_fs_download (void *cls) | ||
1323 | { | ||
1324 | struct GNUNET_FS_DownloadContext *dc = cls; | ||
1325 | struct GNUNET_FS_ProgressInfo pi; | ||
1326 | |||
1327 | if (NULL != dc->th) | ||
1328 | { | ||
1329 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); | ||
1330 | dc->th = NULL; | ||
1331 | } | ||
1332 | if (NULL != dc->client) | ||
1333 | { | ||
1334 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | ||
1335 | dc->client = NULL; | ||
1336 | } | ||
1337 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_INACTIVE; | ||
1338 | make_download_status (&pi, dc); | ||
1339 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, | ||
1340 | &pi); | ||
1341 | } | ||
1342 | |||
1343 | |||
1276 | /** | 1344 | /** |
1277 | * Download parts of a file. Note that this will store | 1345 | * Download parts of a file. Note that this will store |
1278 | * the blocks at the respective offset in the given file. Also, the | 1346 | * the blocks at the respective offset in the given file. Also, the |
@@ -1318,7 +1386,6 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | |||
1318 | { | 1386 | { |
1319 | struct GNUNET_FS_ProgressInfo pi; | 1387 | struct GNUNET_FS_ProgressInfo pi; |
1320 | struct GNUNET_FS_DownloadContext *dc; | 1388 | struct GNUNET_FS_DownloadContext *dc; |
1321 | struct GNUNET_CLIENT_Connection *client; | ||
1322 | 1389 | ||
1323 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri)); | 1390 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri)); |
1324 | if ( (offset + length < offset) || | 1391 | if ( (offset + length < offset) || |
@@ -1401,26 +1468,15 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | |||
1401 | pi.value.download.specifics.start.meta = meta; | 1468 | pi.value.download.specifics.start.meta = meta; |
1402 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, | 1469 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, |
1403 | &pi); | 1470 | &pi); |
1404 | |||
1405 | |||
1406 | // FIXME: bound parallelism here | ||
1407 | client = GNUNET_CLIENT_connect (h->sched, | ||
1408 | "fs", | ||
1409 | h->cfg); | ||
1410 | GNUNET_assert (NULL != client); | ||
1411 | dc->client = client; | ||
1412 | GNUNET_CLIENT_receive (client, | ||
1413 | &receive_results, | ||
1414 | dc, | ||
1415 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1416 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; | ||
1417 | make_download_status (&pi, dc); | ||
1418 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, | ||
1419 | &pi); | ||
1420 | schedule_block_download (dc, | 1471 | schedule_block_download (dc, |
1421 | &dc->uri->data.chk.chk, | 1472 | &dc->uri->data.chk.chk, |
1422 | 0, | 1473 | 0, |
1423 | 1 /* 0 == CHK, 1 == top */); | 1474 | 1 /* 0 == CHK, 1 == top */); |
1475 | dc->job_queue = GNUNET_FS_queue_ (h, | ||
1476 | &activate_fs_download, | ||
1477 | &deactivate_fs_download, | ||
1478 | dc, | ||
1479 | (length + DBLOCK_SIZE-1) / DBLOCK_SIZE); | ||
1424 | return dc; | 1480 | return dc; |
1425 | } | 1481 | } |
1426 | 1482 | ||
@@ -1455,6 +1511,11 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, | |||
1455 | { | 1511 | { |
1456 | struct GNUNET_FS_ProgressInfo pi; | 1512 | struct GNUNET_FS_ProgressInfo pi; |
1457 | 1513 | ||
1514 | if (dc->job_queue != NULL) | ||
1515 | { | ||
1516 | GNUNET_FS_dequeue_ (dc->job_queue); | ||
1517 | dc->job_queue = NULL; | ||
1518 | } | ||
1458 | while (NULL != dc->child_head) | 1519 | while (NULL != dc->child_head) |
1459 | GNUNET_FS_download_stop (dc->child_head, | 1520 | GNUNET_FS_download_stop (dc->child_head, |
1460 | do_delete); | 1521 | do_delete); |
@@ -1472,13 +1533,6 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, | |||
1472 | if (GNUNET_SCHEDULER_NO_TASK != dc->task) | 1533 | if (GNUNET_SCHEDULER_NO_TASK != dc->task) |
1473 | GNUNET_SCHEDULER_cancel (dc->h->sched, | 1534 | GNUNET_SCHEDULER_cancel (dc->h->sched, |
1474 | dc->task); | 1535 | dc->task); |
1475 | if (NULL != dc->th) | ||
1476 | { | ||
1477 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); | ||
1478 | dc->th = NULL; | ||
1479 | } | ||
1480 | if (NULL != dc->client) | ||
1481 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | ||
1482 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, | 1536 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, |
1483 | &free_entry, | 1537 | &free_entry, |
1484 | NULL); | 1538 | NULL); |
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 294d3d454..c75b21668 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c | |||
@@ -1022,19 +1022,10 @@ search_result_free (void *cls, | |||
1022 | GNUNET_FS_uri_destroy (sr->uri); | 1022 | GNUNET_FS_uri_destroy (sr->uri); |
1023 | GNUNET_CONTAINER_meta_data_destroy (sr->meta); | 1023 | GNUNET_CONTAINER_meta_data_destroy (sr->meta); |
1024 | if (sr->probe_ctx != NULL) | 1024 | if (sr->probe_ctx != NULL) |
1025 | { | 1025 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); |
1026 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); | ||
1027 | h->active_probes--; | ||
1028 | /* FIXME: trigger starting of new | ||
1029 | probes here!? Maybe not -- could | ||
1030 | cause new probes to be immediately | ||
1031 | stopped again... */ | ||
1032 | } | ||
1033 | if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) | 1026 | if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) |
1034 | { | 1027 | GNUNET_SCHEDULER_cancel (h->sched, |
1035 | GNUNET_SCHEDULER_cancel (h->sched, | 1028 | sr->probe_cancel_task); |
1036 | sr->probe_cancel_task); | ||
1037 | } | ||
1038 | GNUNET_free (sr); | 1029 | GNUNET_free (sr); |
1039 | return GNUNET_OK; | 1030 | return GNUNET_OK; |
1040 | } | 1031 | } |
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c index 6f36e20cb..dd783f406 100644 --- a/src/fs/fs_test_lib.c +++ b/src/fs/fs_test_lib.c | |||
@@ -208,6 +208,9 @@ progress_cb (void *cls, | |||
208 | daemon, | 208 | daemon, |
209 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 209 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
210 | break; | 210 | break; |
211 | case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: | ||
212 | case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: | ||
213 | break; | ||
211 | /* FIXME: monitor data correctness during download progress */ | 214 | /* FIXME: monitor data correctness during download progress */ |
212 | /* FIXME: do performance reports given sufficient verbosity */ | 215 | /* FIXME: do performance reports given sufficient verbosity */ |
213 | /* FIXME: advance timeout task to "immediate" on error */ | 216 | /* FIXME: advance timeout task to "immediate" on error */ |
diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c index d9ab7543d..bbc750026 100644 --- a/src/fs/gnunet-download.c +++ b/src/fs/gnunet-download.c | |||
@@ -138,6 +138,9 @@ progress_cb (void *cls, | |||
138 | NULL, | 138 | NULL, |
139 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 139 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
140 | break; | 140 | break; |
141 | case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: | ||
142 | case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: | ||
143 | break; | ||
141 | default: | 144 | default: |
142 | fprintf (stderr, | 145 | fprintf (stderr, |
143 | _("Unexpected status: %d\n"), | 146 | _("Unexpected status: %d\n"), |
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 64bfda3ba..a228d0263 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h | |||
@@ -1476,7 +1476,15 @@ enum GNUNET_FS_OPTIONS | |||
1476 | * followed by an "unsigned int" giving the desired maximum number | 1476 | * followed by an "unsigned int" giving the desired maximum number |
1477 | * of parallel downloads). | 1477 | * of parallel downloads). |
1478 | */ | 1478 | */ |
1479 | GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM = 1 | 1479 | GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM = 1, |
1480 | |||
1481 | /** | ||
1482 | * Maximum number of requests that should be pending at a given | ||
1483 | * point in time (invidivual downloads may go above this, but | ||
1484 | * if we are above this threshold, we should not activate any | ||
1485 | * additional downloads. | ||
1486 | */ | ||
1487 | GNUNET_FS_OPTIONS_REQUEST_PARALLELISM = 2 | ||
1480 | 1488 | ||
1481 | }; | 1489 | }; |
1482 | 1490 | ||