From 4761d5671197ba3a125d66c672b5f5165ba83481 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Sat, 28 Apr 2012 13:09:31 +0000 Subject: -hashmap for storing lockingrequests in lockmanager --- src/lockmanager/gnunet-service-lockmanager.c | 61 +++++++++- src/lockmanager/lockmanager_api.c | 176 ++++++++++++++++++++------- 2 files changed, 187 insertions(+), 50 deletions(-) diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c index 5735f65b1..65142fec2 100644 --- a/src/lockmanager/gnunet-service-lockmanager.c +++ b/src/lockmanager/gnunet-service-lockmanager.c @@ -35,21 +35,72 @@ #define LOG(kind,...) \ GNUNET_log_from (kind, "gnunet-service-lockmanager",__VA_ARGS__) +#define TIME_REL_MINS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min) + +#define TIMEOUT TIME_REL_MINS(3) + +/** + * Transmit notify for sending message to client + * + * @param cls the message to send + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_notify (void *cls, size_t size, void *buf) +{ + struct GNUNET_LOCKMANAGER_Message *msg = cls; + uint16_t msg_size; + + if ((0 == size) || (NULL == buf)) + { + /* FIXME: Timed out -- requeue? */ + return 0; + } + msg_size = ntohs (msg->header.size); + GNUNET_assert (size >= msg_size); + memcpy (buf, msg, msg_size); + GNUNET_free (msg); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message of size %u sent\n", msg_size); + return msg_size; +} + /** * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE * - * @param - * @return + * @param cls NULL + * @param client the client sending this message + * @param message GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE message */ static void handle_acquire (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - // const struct GNUNET_LOCKMANAGER_Message *msg = message; + const struct GNUNET_LOCKMANAGER_Message *request; + struct GNUNET_LOCKMANAGER_Message *reply; + int16_t request_size; + + LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received a ACQUIRE message\n"); + "Received an ACQUIRE message\n"); + + request = (struct GNUNET_LOCKMANAGER_Message *) message; + + /* FIXME: Dummy implementation; just echos success for every lock */ + request_size = ntohs (message->size); + reply = GNUNET_malloc (request_size); + memcpy (reply, request, request_size); + reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS); + GNUNET_SERVER_notify_transmit_ready (client, + request_size, + TIMEOUT, + &transmit_notify, + reply); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -85,7 +136,7 @@ lockmanager_run (void *cls, struct GNUNET_SERVER_Handle * server, const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_SERVER_MessageHandler message_handlers[] = + static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { {&handle_acquire, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE, 0}, {&handle_release, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE, 0}, diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c index 7e20e27de..6524c7134 100644 --- a/src/lockmanager/lockmanager_api.c +++ b/src/lockmanager/lockmanager_api.c @@ -106,6 +106,63 @@ struct GNUNET_LOCKMANAGER_LockingRequest }; +/** + * Generate hash with domain name and the lock + * + * @param domain NULL terminated domain name + * + * @param domain_length the length of the domain name including the terminating + * NULL if already known; 0 to calculate + * + * @param lock the lock number + * @param where to write the generated hash + */ +static void +hash_domain_and_lock (const char *domain, + uint16_t domain_length, + uint32_t lock, + GNUNET_HashCode *ret) +{ + unsigned int str_len; + uint32_t *block; + size_t block_size; + + str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; + block_size = sizeof (uint32_t) + str_len; + block = GNUNET_malloc (block_size); + /* Copy data */ + *block = lock; + memcpy (&block[1], domain, str_len); + + GNUNET_CRYPTO_hash (block, block_size, ret); + GNUNET_free (block); +} + + +/** + * Task for calling status change callback for a lock + * + * @param cls the LockingRequest associated with this lock + * @param tc the TaskScheduler context + */ +static void +call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; + + if (NULL != r->status_cb) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling status change callback for lock: %d in domain: %s\n", + r->lock, r->domain); + r->status_cb (r->status_cb_cls, + r->domain, + r->lock, + r->status); + } +} + + /** * Handler for server replies * @@ -116,13 +173,68 @@ static void handle_replies (void *cls, const struct GNUNET_MessageHeader *msg) { + struct GNUNET_LOCKMANAGER_Handle *handle = cls; + if (NULL == msg) - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Lockmanager service not available or went down\n"); - return; + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Lockmanager service not available or went down\n"); + return; + } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received SUCCESS message\n"); + switch (ntohs (msg->type)) + { + case GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received SUCCESS message\n"); + + const struct GNUNET_LOCKMANAGER_Message *m; + const char *domain; + struct GNUNET_HashCode hash; + uint32_t lock; + int match_found; + + m = (struct GNUNET_LOCKMANAGER_Message *) msg; + domain = (char *) &m[1]; + lock = ntohl (m->lock); + hash_domain_and_lock (domain, 0, lock, &hash); + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "\t on lock: %d in domain %s\n", + lock, domain); + + int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) + { + struct GNUNET_LOCKMANAGER_LockingRequest *r = value; + + if ( !((0 != strcmp (domain, r->domain)) + && (lock == r->lock))) + return GNUNET_YES; + + match_found = GNUNET_YES; + if (GNUNET_LOCKMANAGER_SUCCESS != r->status) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Changing status for lock: %d in domain: %s to SUCCESS\n", + r->lock, r->domain); + r->status = GNUNET_LOCKMANAGER_SUCCESS; + GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, + r, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + } + return GNUNET_NO; + } + + match_found = GNUNET_NO; + GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, + &hash, + &match_iterator, + NULL); + GNUNET_assert (GNUNET_YES == match_found); + break; + default: + GNUNET_break(0); + } } @@ -160,7 +272,7 @@ transmit_notify (void *cls, size_t size, void *buf) * * @param cls NULL * @param key current key code - * @param value value in the hash map + * @param value the Locking request * @return GNUNET_YES if we should continue to * iterate, * GNUNET_NO if not. @@ -170,49 +282,21 @@ free_iterator(void *cls, const GNUNET_HashCode * key, void *value) { + struct GNUNET_LOCKMANAGER_LockingRequest *r = value; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Clearing locking request\n"); - GNUNET_free (value); + GNUNET_free (r->domain); + GNUNET_free (r); return GNUNET_YES; } -/** - * Generate hash with domain name and the lock - * - * @param domain NULL terminated domain name - * - * @param domain_length the length of the domain name including the terminating - * NULL if already known; 0 to calculate - * - * @param lock the lock number - * @param where to write the generated hash - */ -static void -hash_domain_and_lock (const char *domain, - uint16_t domain_length, - uint32_t lock, - GNUNET_HashCode *ret) -{ - unsigned int str_len; - uint32_t *block; - size_t block_size; - - str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; - block_size = sizeof (uint32_t) + str_len; - block = GNUNET_malloc (block_size); - /* Copy data */ - *block = lock; - memcpy (&block[1], domain, str_len); - - GNUNET_CRYPTO_hash (block, block_size, ret); - GNUNET_free (block); -} - /*******************/ /* API Definitions */ /*******************/ + /** * Connect to the lockmanager service * @@ -240,7 +324,7 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_CLIENT_receive (h->conn, &handle_replies, - NULL, + h, GNUNET_TIME_UNIT_FOREVER_REL); LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); @@ -318,6 +402,7 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, r->handle = handle; r->lock = lock; r->domain = GNUNET_malloc (r->domain_name_length); + r->status = GNUNET_LOCKMANAGER_RELEASE; memcpy (r->domain, domain_name, r->domain_name_length); msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length; @@ -332,8 +417,8 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, msg_size, TIMEOUT, - GNUNET_NO, - *transmit_notify, + GNUNET_YES, + &transmit_notify, msg); hash_domain_and_lock (r->domain, r->domain_name_length, @@ -386,8 +471,7 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest &transmit_notify, msg); } - LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); - + hash_domain_and_lock (request->domain, request->domain_name_length, request->lock, @@ -396,6 +480,8 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (request->handle->hashmap, &hash, request)); - + + GNUNET_free (request->domain); GNUNET_free (request); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); } -- cgit v1.2.3