From 7d1c10c4b0cf298d12eeac4425f27207d28ab428 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 16 Sep 2009 15:44:32 +0000 Subject: [PATCH] stuff --- src/fs/gnunet-service-fs.c | 185 +++++++++++++++++++++++++++++++++++-- src/util/Makefile.am | 1 + src/util/container_heap.c | 11 +-- 3 files changed, 182 insertions(+), 15 deletions(-) diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 5237cee04..0a9fbcefe 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c @@ -24,7 +24,7 @@ * @author Christian Grothoff * * TODO: - * - tracking of PendingRequests (and defining that struct...) + * - tracking of PendingRequests * - setup P2P search on CS request * - setup P2P search on P2P GET * - forward replies based on tracked requests @@ -341,6 +341,13 @@ struct ProcessGetContext }; +/** + * All requests from a client are + * kept in a doubly-linked list. + */ +struct ClientRequestList; + + /** * Information we keep for each pending request. We should try to * keep this struct as small as possible since its memory consumption @@ -355,6 +362,13 @@ struct PendingRequest */ struct GNUNET_SERVER_Client *client; + /** + * If this request was made by a client, + * this is our entry in the client request + * list; otherwise NULL. + */ + struct ClientRequestList *crl_entry; + /** * If this is a namespace query, pointer to the hash of the public * key of the namespace; otherwise NULL. @@ -451,6 +465,60 @@ struct PendingRequest }; +/** + * All requests from a client are + * kept in a doubly-linked list. + */ +struct ClientRequestList +{ + /** + * This is a doubly-linked list. + */ + struct ClientRequestList *next; + + /** + * This is a doubly-linked list. + */ + struct ClientRequestList *prev; + + /** + * A request from this client. + */ + struct PendingRequest *req; + +}; + + +/** + * Linked list of all clients that we are + * currently processing requests for. + */ +struct ClientList +{ + + /** + * This is a linked list. + */ + struct ClientList *next; + + /** + * What client is this entry for? + */ + struct GNUNET_SERVER_Client* client; + + /** + * Head of the DLL of requests from this client. + */ + struct ClientRequestList *head; + + /** + * Tail of the DLL of requests from this client. + */ + struct ClientRequestList *tail; + +}; + + /** * Closure for "process_reply" function. */ @@ -505,8 +573,7 @@ static struct GNUNET_SCHEDULER_Handle *sched; const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Handle to the core service (NULL until we've - * connected to it). + * Handle to the core service (NULL until we've connected to it). */ struct GNUNET_CORE_Handle *core; @@ -543,6 +610,27 @@ static struct IndexInfo *indexed_files; */ static struct GNUNET_CONTAINER_MultiHashMap *ifm; +/** + * Map of query hash codes to requests. + */ +static struct GNUNET_CONTAINER_MultiHashMap *requests_by_query; + +/** + * Map of peer IDs to requests (for those requests coming + * from other peers). + */ +static struct GNUNET_CONTAINER_MultiHashMap *requests_by_peer; + +/** + * Linked list of all of our clients and their requests. + */ +static struct ClientList *clients; + +/** + * Heap with the request that will expire next at the top. + */ +static struct GNUNET_CONTAINER_Heap *requests_by_expiration; + /** * Write the current index information list to disk. @@ -1467,6 +1555,35 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = { }; +/** + * Clean up the memory used by the PendingRequest + * structure (except for the client or peer list + * that the request may be part of). + * + * @param pr request to clean up + */ +static void +destroy_pending_request (struct PendingRequest *pr) +{ + GNUNET_CONTAINER_multihashmap_remove (requests_by_query, + &pr->query, + pr); + // FIXME: not sure how this can work (efficiently) + // also, what does the return value mean? + GNUNET_CONTAINER_heap_remove_node (requests_by_expiration, + pr); + if (NULL != pr->bf) + GNUNET_CONTAINER_bloomfilter_free (pr->bf); + GNUNET_PEER_change_rc (pr->source_pid, -1); + GNUNET_PEER_change_rc (pr->target_pid, -1); + GNUNET_PEER_decrement_rcs (pr->used_pids, pr->used_pids_off); + GNUNET_free_non_null (pr->used_pids); + GNUNET_free_non_null (pr->replies_seen); + GNUNET_free_non_null (pr->namespace); + GNUNET_free (pr); +} + + /** * A client disconnected. Remove all of its pending queries. * @@ -1479,14 +1596,38 @@ handle_client_disconnect (void *cls, * client) { struct LocalGetContext *lgc; + struct ClientList *cpos; + struct ClientList *cprev; + struct ClientRequestList *rl; lgc = lgc_head; while ( (NULL != lgc) && (lgc->client != client) ) lgc = lgc->next; - if (lgc == NULL) - return; /* not one of our clients */ - local_get_context_free (lgc); + if (lgc != NULL) + local_get_context_free (lgc); + cprev = NULL; + cpos = clients; + while ( (NULL != cpos) && + (clients->client != client) ) + { + cprev = cpos; + cpos = cpos->next; + } + if (cpos != NULL) + { + if (cprev == NULL) + clients = cpos->next; + else + cprev->next = cpos->next; + while (NULL != (rl = cpos->head)) + { + cpos->head = rl->next; + destroy_pending_request (rl->req); + GNUNET_free (rl); + } + GNUNET_free (cpos); + } } @@ -1520,6 +1661,30 @@ shutdown_task (void *cls, } +/** + * Free (each) request made by the peer. + * + * @param cls closure, points to peer that the request belongs to + * @param key current key code + * @param value value in the hash map + * @return GNUNET_YES (we should continue to iterate) + */ +static int +destroy_request (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + const struct GNUNET_PeerIdentity * peer = cls; + struct PendingRequest *pr = value; + + GNUNET_CONTAINER_multihashmap_remove (requests_by_peer, + &peer->hashPubKey, + pr); + destroy_pending_request (pr); + return GNUNET_YES; +} + + /** * Method called whenever a peer disconnects. * @@ -1531,9 +1696,10 @@ peer_disconnect_handler (void *cls, const struct GNUNET_PeerIdentity * peer) { - // FIXME: remove all pending requests from this - // peer from our memory - // (iterate over request_map) + GNUNET_CONTAINER_multihashmap_get_multiple (requests_by_peer, + &peer->hashPubKey, + &destroy_request, + (void*) peer); } @@ -1565,6 +1731,7 @@ forward_get_request (void *cls, * the target buffer "buf". "buf" will be * NULL and "size" zero if the socket was closed for * writing in the meantime. In that case, only + * free the message * * @param cls closure, pointer to the message diff --git a/src/util/Makefile.am b/src/util/Makefile.am index d7e5ada54..c0e64b3f4 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -24,6 +24,7 @@ libgnunetutil_la_SOURCES = \ configuration.c \ connection.c \ container_bloomfilter.c \ + container_heap.c \ container_meta_data.c \ container_multihashmap.c \ crypto_aes.c \ diff --git a/src/util/container_heap.c b/src/util/container_heap.c index b5ccd7950..7e41c40f2 100644 --- a/src/util/container_heap.c +++ b/src/util/container_heap.c @@ -26,8 +26,7 @@ #include "platform.h" #include "gnunet_protocols.h" -#include "gnunet_util.h" -#include "gnunet_util_containers.h" +#include "gnunet_util_lib.h" /* * Struct that is stored in hashmap, pointers to @@ -65,7 +64,7 @@ struct GNUNET_CONTAINER_Heap unsigned int max_size; - enum type; + enum GNUNET_CONTAINER_HeapOrder type; struct GNUNET_CONTAINER_heap_node *root; @@ -96,7 +95,7 @@ printTree (struct GNUNET_CONTAINER_Heap *root) } struct GNUNET_CONTAINER_Heap * -GNUNET_CONTAINER_heap_create (enum type) +GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder type) { struct GNUNET_CONTAINER_Heap *heap; heap = malloc (sizeof (struct GNUNET_CONTAINER_Heap)); @@ -491,7 +490,7 @@ internal_iterator (struct GNUNET_CONTAINER_Heap *root, return; internal_iterator (root, node->left_child, iterator, cls); internal_iterator (root, node->right_child, iterator, cls); - iterator (node->element, node->cost, root, cls); + iterator (cls, node->element, node->cost); } int @@ -519,7 +518,7 @@ GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *root) element = root->traversal_pos->element; - choice = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2); + choice = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2); switch (choice) { -- 2.25.1