aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO13
-rw-r--r--src/fs/fs.c136
-rw-r--r--src/fs/fs.h54
-rw-r--r--src/fs/fs_download.c114
-rw-r--r--src/fs/fs_search.c15
-rw-r--r--src/fs/fs_test_lib.c3
-rw-r--r--src/fs/gnunet-download.c3
-rw-r--r--src/include/gnunet_fs_service.h10
8 files changed, 233 insertions, 115 deletions
diff --git a/TODO b/TODO
index a4393324c..3db19b785 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,9 @@
10.9.0pre1: 10.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 */
131struct GNUNET_FS_QueueEntry * 158struct 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,
166void 193void
167GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) 194GNUNET_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 */
463typedef void (*GNUNET_FS_QueueStop)(void *cls); 463typedef void (*GNUNET_FS_QueueStop)(void *cls);
464 464
465/**
466 * Categories of jobs in the FS queue.
467 */
468enum 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 */
557struct GNUNET_FS_QueueEntry * 547struct 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 */
1284static void
1285activate_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 */
1321static void
1322deactivate_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