From: Christian Grothoff Date: Mon, 8 Mar 2010 20:22:09 +0000 (+0000) Subject: drq clean up X-Git-Tag: initial-import-from-subversion-38251~22537 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5;p=oweals%2Fgnunet.git drq clean up --- 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 = \ test_fs_start_stop \ test_fs_unindex \ test_fs_uri \ - test_fs_test_lib -# test_gnunet_service_fs_p2p + test_fs_test_lib \ + test_gnunet_service_fs_p2p # $(check_PROGRAMS) 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 @@ #include "fs.h" #include "fs_tree.h" -#define DEBUG_DOWNLOAD GNUNET_YES +#define DEBUG_DOWNLOAD GNUNET_NO /** * 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 @@ #include "gnunet_protocols.h" #include "fs.h" -#define DEBUG_SEARCH GNUNET_YES +#define DEBUG_SEARCH GNUNET_NO 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 HOSTNAME = localhost #TOTAL_QUOTA_IN = 3932160 #TOTAL_QUOTA_OUT = 3932160 -DEBUG = YES +#DEBUG = YES [fs] PORT = 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 struct DatastoreRequestQueue *prev; /** - * Function to call (will issue the request). + * Function to call for each entry. + */ + GNUNET_DATASTORE_Iterator iter; + + /** + * Closure for iter. */ - RequestFunction req; + void *iter_cls; /** - * Closure for req. + * Key we are doing the 'get' for. */ - void *req_cls; + GNUNET_HashCode key; /** - * When should this request time-out because we don't care anymore? + * Timeout for this operation. */ struct GNUNET_TIME_Absolute timeout; @@ -74,6 +79,11 @@ struct DatastoreRequestQueue */ GNUNET_SCHEDULER_TaskIdentifier task; + /** + * Datastore entry type we are doing the 'get' for. + */ + uint32_t type; + /** * Is this request at the head of the queue irrespective of its * timeout value? @@ -115,21 +125,62 @@ static struct DatastoreRequestQueue *drq_running; /** - * A datastore request had to be timed out. + * Run the next DS request in our queue, we're done with the current + * one. + */ +static void +next_ds_request (); + + +/** + * Wrapper for the datastore get operation. Makes sure to trigger the + * next datastore operation in the queue once the operation is + * complete. * - * @param cls closure (unused) - * @param tc task context, unused + * @param cls our 'struct DatastoreRequestQueue*' + * @param key key for the content + * @param size number of bytes in data + * @param data content stored + * @param type type of the content + * @param priority priority of the content + * @param anonymity anonymity-level for the content + * @param expiration expiration time for the content + * @param uid unique identifier for the datum; + * maybe 0 if no unique identifier is available */ static void -timeout_ds_request (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +get_iterator (void *cls, + const GNUNET_HashCode * key, + uint32_t size, + const void *data, + uint32_t type, + uint32_t priority, + uint32_t anonymity, + struct GNUNET_TIME_Absolute + expiration, + uint64_t uid) { - struct DatastoreRequestQueue *e = cls; + struct DatastoreRequestQueue *gc = cls; - e->task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); - e->req (e->req_cls, GNUNET_NO); - GNUNET_free (e); + if (gc->iter == NULL) + { + /* stop the iteration */ + if (key != NULL) + GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); + } + else + { + gc->iter (gc->iter_cls, + key, size, data, type, + priority, anonymity, expiration, uid); + } + if (key == NULL) + { + GNUNET_assert (gc == drq_running); + GNUNET_free (gc); + drq_running = NULL; + next_ds_request (); + } } @@ -143,9 +194,13 @@ static void run_next_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct DatastoreRequestQueue *e = cls; - - e->req (e->req_cls, GNUNET_YES); + struct DatastoreRequestQueue *gc = cls; + + gc->task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_DATASTORE_get (dsh, &gc->key, gc->type, + &get_iterator, + gc, + GNUNET_TIME_absolute_get_remaining(gc->timeout)); } @@ -173,65 +228,24 @@ next_ds_request () /** - * Remove a pending request from the request queue. + * A datastore request had to be timed out. * - * @param req request to remove + * @param cls closure (unused) + * @param tc task context, unused */ static void -dequeue_ds_request (struct DatastoreRequestQueue *req) -{ - GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, req); - GNUNET_SCHEDULER_cancel (sched, req->task); - GNUNET_free (req); -} - - -/** - * Queue a request for the datastore. - * - * @param deadline by when the request should run - * @param fun function to call once the request can be run - * @param fun_cls closure for fun - * @param immediate should this be queued immediately at - * the head of the queue (irrespecitive of the deadline)? - * @return handle that can be used to dequeue the request - */ -static struct DatastoreRequestQueue * -queue_ds_request (struct GNUNET_TIME_Relative deadline, - RequestFunction fun, - void *fun_cls, - int immediate) +timeout_ds_request (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct DatastoreRequestQueue *e; - struct DatastoreRequestQueue *bef; + struct DatastoreRequestQueue *e = cls; - e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); - e->timeout = GNUNET_TIME_relative_to_absolute (deadline); - e->req = fun; - e->req_cls = fun_cls; - e->forced_head = immediate; - if (GNUNET_YES == immediate) - { - /* local request, highest prio, put at head of queue - regardless of deadline */ - bef = NULL; - } - else - { - bef = drq_tail; - while ( (NULL != bef) && - (e->timeout.value < bef->timeout.value) && - (GNUNET_YES != e->forced_head) ) - bef = bef->prev; - } - GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e); - e->task = GNUNET_SCHEDULER_add_delayed (sched, - deadline, - &timeout_ds_request, - e); - if (drq_running == NULL) - next_ds_request (); - return e; + e->task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); + if (e->iter != NULL) + e->iter (e->iter_cls, + NULL, 0, NULL, 0, 0, 0, + GNUNET_TIME_UNIT_ZERO_ABS, 0); + GNUNET_free (e); } @@ -255,126 +269,16 @@ shutdown_task (void *cls, { drq_head = drq->next; GNUNET_SCHEDULER_cancel (sched, drq->task); - drq->req (drq->req_cls, GNUNET_NO); + if (drq->iter != NULL) + drq->iter (drq->iter_cls, + NULL, 0, NULL, 0, 0, 0, + GNUNET_TIME_UNIT_ZERO_ABS, 0); GNUNET_free (drq); } drq_tail = NULL; } -/** - * Closure for 'do_get' and 'get_iterator'. - */ -struct GetClosure -{ - /** - * Key we are doing the 'get' for. - */ - GNUNET_HashCode key; - - /** - * Datastore entry type we are doing the 'get' for. - */ - uint32_t type; - - /** - * Function to call for each entry. - */ - GNUNET_DATASTORE_Iterator iter; - - /** - * Closure for iter. - */ - void *iter_cls; - - /** - * Timeout for this operation. - */ - struct GNUNET_TIME_Absolute timeout; -}; - - -/** - * Wrapper for the datastore get operation. Makes sure to trigger the - * next datastore operation in the queue once the operation is - * complete. - * - * @param cls our 'struct GetClosure*' - * @param key key for the content - * @param size number of bytes in data - * @param data content stored - * @param type type of the content - * @param priority priority of the content - * @param anonymity anonymity-level for the content - * @param expiration expiration time for the content - * @param uid unique identifier for the datum; - * maybe 0 if no unique identifier is available - */ -static void -get_iterator (void *cls, - const GNUNET_HashCode * key, - uint32_t size, - const void *data, - uint32_t type, - uint32_t priority, - uint32_t anonymity, - struct GNUNET_TIME_Absolute - expiration, - uint64_t uid) -{ - struct GetClosure *gc = cls; - - if (gc->iter == NULL) - { - /* stop the iteration */ - if (key != NULL) - GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); - } - else - { - gc->iter (gc->iter_cls, - key, size, data, type, - priority, anonymity, expiration, uid); - } - if (key == NULL) - { - next_ds_request (); - GNUNET_free (gc); - } -} - - -/** - * We're at the head of the reqeust queue, execute the - * get operation (or signal error). - * - * @param cls the 'struct GetClosure' - * @param ok GNUNET_OK if we can run the GET, otherwise - * we need to time out - */ -static void -do_get (void *cls, - int ok) -{ - struct GetClosure *gc = cls; - - if (ok != GNUNET_OK) - { - if (gc->iter != NULL) - gc->iter (gc->iter_cls, - NULL, 0, NULL, 0, 0, 0, - GNUNET_TIME_UNIT_ZERO_ABS, 0); - GNUNET_free (gc); - next_ds_request (); - return; - } - GNUNET_DATASTORE_get (dsh, &gc->key, gc->type, - &get_iterator, - gc, - GNUNET_TIME_absolute_get_remaining(gc->timeout)); -} - - /** * Iterate over the results for a particular key * in the datastore. The iterator will only be called @@ -399,18 +303,39 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key, struct GNUNET_TIME_Relative timeout, int immediate) { - struct GetClosure *gc; - - gc = GNUNET_malloc (sizeof (struct GetClosure)); - gc->key = *key; - gc->type = type; - gc->iter = iter; - gc->iter_cls = iter_cls; - gc->timeout = GNUNET_TIME_relative_to_absolute (timeout); - return queue_ds_request (timeout, - &do_get, - gc, - immediate); + struct DatastoreRequestQueue *e; + struct DatastoreRequestQueue *bef; + + e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); + e->timeout = GNUNET_TIME_relative_to_absolute (timeout); + e->forced_head = immediate; + e->key = *key; + e->type = type; + e->iter = iter; + e->iter_cls = iter_cls; + e->timeout = GNUNET_TIME_relative_to_absolute (timeout); + if (GNUNET_YES == immediate) + { + /* local request, highest prio, put at head of queue + regardless of deadline */ + bef = NULL; + } + else + { + bef = drq_tail; + while ( (NULL != bef) && + (e->timeout.value < bef->timeout.value) && + (GNUNET_YES != e->forced_head) ) + bef = bef->prev; + } + GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e); + e->task = GNUNET_SCHEDULER_add_delayed (sched, + timeout, + &timeout_ds_request, + e); + if (drq_running == NULL) + next_ds_request (); + return e; } @@ -423,20 +348,20 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key, void GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq) { - struct GetClosure *gc; if (drq == drq_running) { /* 'DATASTORE_get' has already been started (and this call might actually be be legal since it is possible that the client has - not yet received any calls to its the iterator; so we need - to cancel somehow; we do this by getting to the 'GetClosure' - and zeroing the 'iter' field, which stops the iteration */ - gc = drq_running->req_cls; - gc->iter = NULL; + not yet received any calls to its the iterator; so we need to + cancel somehow; we do this by zeroing the 'iter' field, which + stops the iteration */ + drq_running->iter = NULL; } else { - dequeue_ds_request (drq); + GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, drq); + GNUNET_SCHEDULER_cancel (sched, drq->task); + GNUNET_free (drq); } } 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 main (int argc, char *argv[]) { char *const argvx[] = { - "test-gnunet-service-fs-p2p", + "test-fs-test-lib", "-c", "fs_test_lib_data.conf", #if VERBOSE @@ -145,7 +145,7 @@ main (int argc, char *argv[]) }; GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); - GNUNET_log_setup ("test_gnunet_service_fs_p2p", + GNUNET_log_setup ("test_fs_test_lib", #if VERBOSE "DEBUG", #else @@ -153,7 +153,7 @@ main (int argc, char *argv[]) #endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, - argvx, "test-gnunet-service-fs-p2p", + argvx, "test-fs-test-lib", "nohelp", options, &run, NULL); GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); return 0;