aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-03-08 20:22:09 +0000
committerChristian Grothoff <christian@grothoff.org>2010-03-08 20:22:09 +0000
commitdea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5 (patch)
treedd9b43cc9a266f5ed2e80967b8e8600f4e47cc26
parentb5c6d2a78683e5ba002ca226c2bae280a1877bac (diff)
downloadgnunet-dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5.tar.gz
gnunet-dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5.zip
drq clean up
-rw-r--r--src/fs/Makefile.am4
-rw-r--r--src/fs/fs_download.c2
-rw-r--r--src/fs/fs_search.c2
-rw-r--r--src/fs/fs_test_lib_data.conf2
-rw-r--r--src/fs/gnunet-service-fs_drq.c335
-rw-r--r--src/fs/test_fs_test_lib.c6
6 files changed, 138 insertions, 213 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index ee476e6e0..48b53ef88 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -138,8 +138,8 @@ TESTS = \
138 test_fs_start_stop \ 138 test_fs_start_stop \
139 test_fs_unindex \ 139 test_fs_unindex \
140 test_fs_uri \ 140 test_fs_uri \
141 test_fs_test_lib 141 test_fs_test_lib \
142# test_gnunet_service_fs_p2p 142 test_gnunet_service_fs_p2p
143# $(check_PROGRAMS) 143# $(check_PROGRAMS)
144 144
145 145
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index 7776f4b8b..1cd10f830 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -36,7 +36,7 @@
36#include "fs.h" 36#include "fs.h"
37#include "fs_tree.h" 37#include "fs_tree.h"
38 38
39#define DEBUG_DOWNLOAD GNUNET_YES 39#define DEBUG_DOWNLOAD GNUNET_NO
40 40
41/** 41/**
42 * We're storing the IBLOCKS after the 42 * We're storing the IBLOCKS after the
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 3229733de..90a28052f 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -38,7 +38,7 @@
38#include "gnunet_protocols.h" 38#include "gnunet_protocols.h"
39#include "fs.h" 39#include "fs.h"
40 40
41#define DEBUG_SEARCH GNUNET_YES 41#define DEBUG_SEARCH GNUNET_NO
42 42
43 43
44 44
diff --git a/src/fs/fs_test_lib_data.conf b/src/fs/fs_test_lib_data.conf
index a901d2be3..70b47a9d8 100644
--- a/src/fs/fs_test_lib_data.conf
+++ b/src/fs/fs_test_lib_data.conf
@@ -40,7 +40,7 @@ PORT = 43470
40HOSTNAME = localhost 40HOSTNAME = localhost
41#TOTAL_QUOTA_IN = 3932160 41#TOTAL_QUOTA_IN = 3932160
42#TOTAL_QUOTA_OUT = 3932160 42#TOTAL_QUOTA_OUT = 3932160
43DEBUG = YES 43#DEBUG = YES
44 44
45[fs] 45[fs]
46PORT = 43471 46PORT = 43471
diff --git a/src/fs/gnunet-service-fs_drq.c b/src/fs/gnunet-service-fs_drq.c
index fd5614606..dc9560be6 100644
--- a/src/fs/gnunet-service-fs_drq.c
+++ b/src/fs/gnunet-service-fs_drq.c
@@ -55,17 +55,22 @@ struct DatastoreRequestQueue
55 struct DatastoreRequestQueue *prev; 55 struct DatastoreRequestQueue *prev;
56 56
57 /** 57 /**
58 * Function to call (will issue the request). 58 * Function to call for each entry.
59 */
60 GNUNET_DATASTORE_Iterator iter;
61
62 /**
63 * Closure for iter.
59 */ 64 */
60 RequestFunction req; 65 void *iter_cls;
61 66
62 /** 67 /**
63 * Closure for req. 68 * Key we are doing the 'get' for.
64 */ 69 */
65 void *req_cls; 70 GNUNET_HashCode key;
66 71
67 /** 72 /**
68 * When should this request time-out because we don't care anymore? 73 * Timeout for this operation.
69 */ 74 */
70 struct GNUNET_TIME_Absolute timeout; 75 struct GNUNET_TIME_Absolute timeout;
71 76
@@ -75,6 +80,11 @@ struct DatastoreRequestQueue
75 GNUNET_SCHEDULER_TaskIdentifier task; 80 GNUNET_SCHEDULER_TaskIdentifier task;
76 81
77 /** 82 /**
83 * Datastore entry type we are doing the 'get' for.
84 */
85 uint32_t type;
86
87 /**
78 * Is this request at the head of the queue irrespective of its 88 * Is this request at the head of the queue irrespective of its
79 * timeout value? 89 * timeout value?
80 */ 90 */
@@ -115,21 +125,62 @@ static struct DatastoreRequestQueue *drq_running;
115 125
116 126
117/** 127/**
118 * A datastore request had to be timed out. 128 * Run the next DS request in our queue, we're done with the current
129 * one.
130 */
131static void
132next_ds_request ();
133
134
135/**
136 * Wrapper for the datastore get operation. Makes sure to trigger the
137 * next datastore operation in the queue once the operation is
138 * complete.
119 * 139 *
120 * @param cls closure (unused) 140 * @param cls our 'struct DatastoreRequestQueue*'
121 * @param tc task context, unused 141 * @param key key for the content
142 * @param size number of bytes in data
143 * @param data content stored
144 * @param type type of the content
145 * @param priority priority of the content
146 * @param anonymity anonymity-level for the content
147 * @param expiration expiration time for the content
148 * @param uid unique identifier for the datum;
149 * maybe 0 if no unique identifier is available
122 */ 150 */
123static void 151static void
124timeout_ds_request (void *cls, 152get_iterator (void *cls,
125 const struct GNUNET_SCHEDULER_TaskContext *tc) 153 const GNUNET_HashCode * key,
154 uint32_t size,
155 const void *data,
156 uint32_t type,
157 uint32_t priority,
158 uint32_t anonymity,
159 struct GNUNET_TIME_Absolute
160 expiration,
161 uint64_t uid)
126{ 162{
127 struct DatastoreRequestQueue *e = cls; 163 struct DatastoreRequestQueue *gc = cls;
128 164
129 e->task = GNUNET_SCHEDULER_NO_TASK; 165 if (gc->iter == NULL)
130 GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); 166 {
131 e->req (e->req_cls, GNUNET_NO); 167 /* stop the iteration */
132 GNUNET_free (e); 168 if (key != NULL)
169 GNUNET_DATASTORE_get_next (dsh, GNUNET_NO);
170 }
171 else
172 {
173 gc->iter (gc->iter_cls,
174 key, size, data, type,
175 priority, anonymity, expiration, uid);
176 }
177 if (key == NULL)
178 {
179 GNUNET_assert (gc == drq_running);
180 GNUNET_free (gc);
181 drq_running = NULL;
182 next_ds_request ();
183 }
133} 184}
134 185
135 186
@@ -143,9 +194,13 @@ static void
143run_next_request (void *cls, 194run_next_request (void *cls,
144 const struct GNUNET_SCHEDULER_TaskContext *tc) 195 const struct GNUNET_SCHEDULER_TaskContext *tc)
145{ 196{
146 struct DatastoreRequestQueue *e = cls; 197 struct DatastoreRequestQueue *gc = cls;
147 198
148 e->req (e->req_cls, GNUNET_YES); 199 gc->task = GNUNET_SCHEDULER_NO_TASK;
200 GNUNET_DATASTORE_get (dsh, &gc->key, gc->type,
201 &get_iterator,
202 gc,
203 GNUNET_TIME_absolute_get_remaining(gc->timeout));
149} 204}
150 205
151 206
@@ -173,65 +228,24 @@ next_ds_request ()
173 228
174 229
175/** 230/**
176 * Remove a pending request from the request queue. 231 * A datastore request had to be timed out.
177 * 232 *
178 * @param req request to remove 233 * @param cls closure (unused)
234 * @param tc task context, unused
179 */ 235 */
180static void 236static void
181dequeue_ds_request (struct DatastoreRequestQueue *req) 237timeout_ds_request (void *cls,
182{ 238 const struct GNUNET_SCHEDULER_TaskContext *tc)
183 GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, req);
184 GNUNET_SCHEDULER_cancel (sched, req->task);
185 GNUNET_free (req);
186}
187
188
189/**
190 * Queue a request for the datastore.
191 *
192 * @param deadline by when the request should run
193 * @param fun function to call once the request can be run
194 * @param fun_cls closure for fun
195 * @param immediate should this be queued immediately at
196 * the head of the queue (irrespecitive of the deadline)?
197 * @return handle that can be used to dequeue the request
198 */
199static struct DatastoreRequestQueue *
200queue_ds_request (struct GNUNET_TIME_Relative deadline,
201 RequestFunction fun,
202 void *fun_cls,
203 int immediate)
204{ 239{
205 struct DatastoreRequestQueue *e; 240 struct DatastoreRequestQueue *e = cls;
206 struct DatastoreRequestQueue *bef;
207 241
208 e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); 242 e->task = GNUNET_SCHEDULER_NO_TASK;
209 e->timeout = GNUNET_TIME_relative_to_absolute (deadline); 243 GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e);
210 e->req = fun; 244 if (e->iter != NULL)
211 e->req_cls = fun_cls; 245 e->iter (e->iter_cls,
212 e->forced_head = immediate; 246 NULL, 0, NULL, 0, 0, 0,
213 if (GNUNET_YES == immediate) 247 GNUNET_TIME_UNIT_ZERO_ABS, 0);
214 { 248 GNUNET_free (e);
215 /* local request, highest prio, put at head of queue
216 regardless of deadline */
217 bef = NULL;
218 }
219 else
220 {
221 bef = drq_tail;
222 while ( (NULL != bef) &&
223 (e->timeout.value < bef->timeout.value) &&
224 (GNUNET_YES != e->forced_head) )
225 bef = bef->prev;
226 }
227 GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e);
228 e->task = GNUNET_SCHEDULER_add_delayed (sched,
229 deadline,
230 &timeout_ds_request,
231 e);
232 if (drq_running == NULL)
233 next_ds_request ();
234 return e;
235} 249}
236 250
237 251
@@ -255,7 +269,10 @@ shutdown_task (void *cls,
255 { 269 {
256 drq_head = drq->next; 270 drq_head = drq->next;
257 GNUNET_SCHEDULER_cancel (sched, drq->task); 271 GNUNET_SCHEDULER_cancel (sched, drq->task);
258 drq->req (drq->req_cls, GNUNET_NO); 272 if (drq->iter != NULL)
273 drq->iter (drq->iter_cls,
274 NULL, 0, NULL, 0, 0, 0,
275 GNUNET_TIME_UNIT_ZERO_ABS, 0);
259 GNUNET_free (drq); 276 GNUNET_free (drq);
260 } 277 }
261 drq_tail = NULL; 278 drq_tail = NULL;
@@ -263,119 +280,6 @@ shutdown_task (void *cls,
263 280
264 281
265/** 282/**
266 * Closure for 'do_get' and 'get_iterator'.
267 */
268struct GetClosure
269{
270 /**
271 * Key we are doing the 'get' for.
272 */
273 GNUNET_HashCode key;
274
275 /**
276 * Datastore entry type we are doing the 'get' for.
277 */
278 uint32_t type;
279
280 /**
281 * Function to call for each entry.
282 */
283 GNUNET_DATASTORE_Iterator iter;
284
285 /**
286 * Closure for iter.
287 */
288 void *iter_cls;
289
290 /**
291 * Timeout for this operation.
292 */
293 struct GNUNET_TIME_Absolute timeout;
294};
295
296
297/**
298 * Wrapper for the datastore get operation. Makes sure to trigger the
299 * next datastore operation in the queue once the operation is
300 * complete.
301 *
302 * @param cls our 'struct GetClosure*'
303 * @param key key for the content
304 * @param size number of bytes in data
305 * @param data content stored
306 * @param type type of the content
307 * @param priority priority of the content
308 * @param anonymity anonymity-level for the content
309 * @param expiration expiration time for the content
310 * @param uid unique identifier for the datum;
311 * maybe 0 if no unique identifier is available
312 */
313static void
314get_iterator (void *cls,
315 const GNUNET_HashCode * key,
316 uint32_t size,
317 const void *data,
318 uint32_t type,
319 uint32_t priority,
320 uint32_t anonymity,
321 struct GNUNET_TIME_Absolute
322 expiration,
323 uint64_t uid)
324{
325 struct GetClosure *gc = cls;
326
327 if (gc->iter == NULL)
328 {
329 /* stop the iteration */
330 if (key != NULL)
331 GNUNET_DATASTORE_get_next (dsh, GNUNET_NO);
332 }
333 else
334 {
335 gc->iter (gc->iter_cls,
336 key, size, data, type,
337 priority, anonymity, expiration, uid);
338 }
339 if (key == NULL)
340 {
341 next_ds_request ();
342 GNUNET_free (gc);
343 }
344}
345
346
347/**
348 * We're at the head of the reqeust queue, execute the
349 * get operation (or signal error).
350 *
351 * @param cls the 'struct GetClosure'
352 * @param ok GNUNET_OK if we can run the GET, otherwise
353 * we need to time out
354 */
355static void
356do_get (void *cls,
357 int ok)
358{
359 struct GetClosure *gc = cls;
360
361 if (ok != GNUNET_OK)
362 {
363 if (gc->iter != NULL)
364 gc->iter (gc->iter_cls,
365 NULL, 0, NULL, 0, 0, 0,
366 GNUNET_TIME_UNIT_ZERO_ABS, 0);
367 GNUNET_free (gc);
368 next_ds_request ();
369 return;
370 }
371 GNUNET_DATASTORE_get (dsh, &gc->key, gc->type,
372 &get_iterator,
373 gc,
374 GNUNET_TIME_absolute_get_remaining(gc->timeout));
375}
376
377
378/**
379 * Iterate over the results for a particular key 283 * Iterate over the results for a particular key
380 * in the datastore. The iterator will only be called 284 * in the datastore. The iterator will only be called
381 * once initially; if the first call did contain a 285 * once initially; if the first call did contain a
@@ -399,18 +303,39 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key,
399 struct GNUNET_TIME_Relative timeout, 303 struct GNUNET_TIME_Relative timeout,
400 int immediate) 304 int immediate)
401{ 305{
402 struct GetClosure *gc; 306 struct DatastoreRequestQueue *e;
403 307 struct DatastoreRequestQueue *bef;
404 gc = GNUNET_malloc (sizeof (struct GetClosure)); 308
405 gc->key = *key; 309 e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue));
406 gc->type = type; 310 e->timeout = GNUNET_TIME_relative_to_absolute (timeout);
407 gc->iter = iter; 311 e->forced_head = immediate;
408 gc->iter_cls = iter_cls; 312 e->key = *key;
409 gc->timeout = GNUNET_TIME_relative_to_absolute (timeout); 313 e->type = type;
410 return queue_ds_request (timeout, 314 e->iter = iter;
411 &do_get, 315 e->iter_cls = iter_cls;
412 gc, 316 e->timeout = GNUNET_TIME_relative_to_absolute (timeout);
413 immediate); 317 if (GNUNET_YES == immediate)
318 {
319 /* local request, highest prio, put at head of queue
320 regardless of deadline */
321 bef = NULL;
322 }
323 else
324 {
325 bef = drq_tail;
326 while ( (NULL != bef) &&
327 (e->timeout.value < bef->timeout.value) &&
328 (GNUNET_YES != e->forced_head) )
329 bef = bef->prev;
330 }
331 GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e);
332 e->task = GNUNET_SCHEDULER_add_delayed (sched,
333 timeout,
334 &timeout_ds_request,
335 e);
336 if (drq_running == NULL)
337 next_ds_request ();
338 return e;
414} 339}
415 340
416 341
@@ -423,20 +348,20 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key,
423void 348void
424GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq) 349GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq)
425{ 350{
426 struct GetClosure *gc;
427 if (drq == drq_running) 351 if (drq == drq_running)
428 { 352 {
429 /* 'DATASTORE_get' has already been started (and this call might 353 /* 'DATASTORE_get' has already been started (and this call might
430 actually be be legal since it is possible that the client has 354 actually be be legal since it is possible that the client has
431 not yet received any calls to its the iterator; so we need 355 not yet received any calls to its the iterator; so we need to
432 to cancel somehow; we do this by getting to the 'GetClosure' 356 cancel somehow; we do this by zeroing the 'iter' field, which
433 and zeroing the 'iter' field, which stops the iteration */ 357 stops the iteration */
434 gc = drq_running->req_cls; 358 drq_running->iter = NULL;
435 gc->iter = NULL;
436 } 359 }
437 else 360 else
438 { 361 {
439 dequeue_ds_request (drq); 362 GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, drq);
363 GNUNET_SCHEDULER_cancel (sched, drq->task);
364 GNUNET_free (drq);
440 } 365 }
441} 366}
442 367
diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c
index d35a91825..0abb539d6 100644
--- a/src/fs/test_fs_test_lib.c
+++ b/src/fs/test_fs_test_lib.c
@@ -132,7 +132,7 @@ int
132main (int argc, char *argv[]) 132main (int argc, char *argv[])
133{ 133{
134 char *const argvx[] = { 134 char *const argvx[] = {
135 "test-gnunet-service-fs-p2p", 135 "test-fs-test-lib",
136 "-c", 136 "-c",
137 "fs_test_lib_data.conf", 137 "fs_test_lib_data.conf",
138#if VERBOSE 138#if VERBOSE
@@ -145,7 +145,7 @@ main (int argc, char *argv[])
145 }; 145 };
146 146
147 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); 147 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/");
148 GNUNET_log_setup ("test_gnunet_service_fs_p2p", 148 GNUNET_log_setup ("test_fs_test_lib",
149#if VERBOSE 149#if VERBOSE
150 "DEBUG", 150 "DEBUG",
151#else 151#else
@@ -153,7 +153,7 @@ main (int argc, char *argv[])
153#endif 153#endif
154 NULL); 154 NULL);
155 GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, 155 GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1,
156 argvx, "test-gnunet-service-fs-p2p", 156 argvx, "test-fs-test-lib",
157 "nohelp", options, &run, NULL); 157 "nohelp", options, &run, NULL);
158 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); 158 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/");
159 return 0; 159 return 0;