-lockmanager acquire retry
[oweals/gnunet.git] / src / lockmanager / lockmanager_api.c
index a026513c95f6a607f461947444d7bde350ee0316..2d2c75d509e02832e11b04870120487f70f3b643 100644 (file)
  * @author Sree Harsha Totakura
  */
 
+/**
+ * To be fixed:
+ *  Should the handle be freed when the connection to service is lost?
+ *  Should cancel_request have a call back (else simultaneous calls break)
+ */
+
 #include "platform.h"
 #include "gnunet_common.h"
 #include "gnunet_container_lib.h"
 
 #define TIMEOUT TIME_REL_MINS(3)
 
+
+/**
+ * The message queue
+ */
+struct MessageQueue
+{
+  /**
+   * The next pointer for doubly linked list
+   */
+  struct MessageQueue *next;
+
+  /**
+   * The prev pointer for doubly linked list
+   */
+  struct MessageQueue *prev;
+  
+  /**
+   * The LOCKMANAGER Message
+   */
+  struct GNUNET_LOCKMANAGER_Message *msg;
+};
+
+
 /**
  * Handler for the lockmanager service
  */
@@ -52,10 +81,30 @@ struct GNUNET_LOCKMANAGER_Handle
    */
   struct GNUNET_CLIENT_Connection *conn;
 
+  /**
+   * The transmit handle for transmissions using conn
+   */
+  struct GNUNET_CLIENT_TransmitHandle *transmit_handle;
+
   /**
    * Hashmap handle
    */
   struct GNUNET_CONTAINER_MultiHashMap *hashmap;
+
+  /**
+   * Double linked list head for message queue
+   */
+  struct MessageQueue *mq_head;
+
+  /**
+   * Double linked list tail for message queue
+   */
+  struct MessageQueue *mq_tail;
+
+  /**
+   * Are we currently handling replies?
+   */
+  int in_replies;
 };
 
 
@@ -79,11 +128,6 @@ struct GNUNET_LOCKMANAGER_LockingRequest
    */
   void *status_cb_cls;
 
-  /**
-   * The pending transmit handle for the ACQUIRE message
-   */
-  struct GNUNET_CLIENT_TransmitHandle *transmit_handle;
-
   /**
    * The locking domain of this request
    */
@@ -98,44 +142,211 @@ struct GNUNET_LOCKMANAGER_LockingRequest
    * The status of the lock
    */
   enum GNUNET_LOCKMANAGER_Status status;
+};
+
+
+/**
+ * Structure for matching a lock
+ */
+struct LockingRequestMatch
+{
+  /**
+   * The matched LockingRequest entry; Should be NULL if no entry is found
+   */
+  struct GNUNET_LOCKMANAGER_LockingRequest *matched_entry;
+
+  /**
+   * The locking domain name of the lock
+   */
+  const char *domain;
 
   /**
-   * The length of the locking domain string including the trailing NULL
+   * The lock number
    */
-  uint16_t domain_name_length;
+  uint32_t lock;
 };
 
 
 /**
- * Generate hash with domain name and the lock
+ * Handler for server replies
  *
- * @param domain NULL terminated domain name
+ * @param cls the LOCKMANAGER_Handle
+ * @param msg received message, NULL on timeout or fatal error
+ */
+static void 
+handle_replies (void *cls,
+                const struct GNUNET_MessageHeader *msg);
+
+
+/**
+ * Transmit notify for sending message to server
  *
- * @param domain_length the length of the domain name including the terminating
- *          NULL if already known; 0 to calculate
+ * @param cls the lockmanager handle
+ * @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_Handle *handle = cls;
+  struct MessageQueue *queue_entity;
+  uint16_t msg_size;
+
+  handle->transmit_handle = NULL;
+  queue_entity = handle->mq_head;
+  GNUNET_assert (NULL != queue_entity);
+  if ((0 == size) || (NULL == buf))
+  {
+    handle->transmit_handle =
+      GNUNET_CLIENT_notify_transmit_ready (handle->conn,
+                                           ntohs
+                                           (queue_entity->msg->header.size),
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           GNUNET_YES,
+                                           &transmit_notify,
+                                           handle);
+    return 0;
+  } 
+  msg_size = ntohs (queue_entity->msg->header.size);
+  GNUNET_assert (size >= msg_size);
+  memcpy (buf, queue_entity->msg, msg_size);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Message of size %u sent\n", msg_size);
+  GNUNET_free (queue_entity->msg);
+  GNUNET_CONTAINER_DLL_remove (handle->mq_head,
+                               handle->mq_tail,
+                               queue_entity);
+  GNUNET_free (queue_entity);
+  queue_entity = handle->mq_head;
+  if (NULL != queue_entity)
+  {
+    handle->transmit_handle =
+      GNUNET_CLIENT_notify_transmit_ready (handle->conn,
+                                           ntohs
+                                           (queue_entity->msg->header.size),
+                                           TIMEOUT,
+                                           GNUNET_YES,
+                                           &transmit_notify,
+                                           handle);
+  }
+  if (GNUNET_NO == handle->in_replies)
+  {
+    GNUNET_CLIENT_receive (handle->conn,
+                           &handle_replies,
+                           handle,
+                           GNUNET_TIME_UNIT_FOREVER_REL);
+    handle->in_replies = GNUNET_YES;
+  }
+  return msg_size;
+}
+
+
+/**
+ * Queues a message into handle's send message queue
  *
- * @param lock the lock number
- * @param where to write the generated hash
+ * @param handle the lockmanager handle whose queue will be used
+ * @param msg the message to be queued
  */
 static void
-hash_domain_and_lock (const char *domain,
-                      uint16_t domain_length,
-                      uint32_t lock,
-                      GNUNET_HashCode *ret)
+queue_message (struct GNUNET_LOCKMANAGER_Handle *handle,
+               struct GNUNET_LOCKMANAGER_Message *msg)
 {
-  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);
+  struct MessageQueue *queue_entity;
+
+  GNUNET_assert (NULL != msg);
+  queue_entity = GNUNET_malloc (sizeof (struct MessageQueue));
+  queue_entity->msg = msg;
+  GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head,
+                                    handle->mq_tail,
+                                    queue_entity);
+  if (NULL == handle->transmit_handle)
+  {
+    handle->transmit_handle =
+      GNUNET_CLIENT_notify_transmit_ready (handle->conn,
+                                           ntohs (msg->header.size),
+                                           TIMEOUT,
+                                           GNUNET_YES,
+                                           &transmit_notify,
+                                           handle);
+  }
+}
+
+
+/**
+ * Get the key for the given lock in the 'lock_map'.
+ *
+ * @param domain_name
+ * @param lock_number
+ * @param key set to the key
+ */
+static void
+get_key (const char *domain_name,
+        uint32_t lock_number,
+        struct GNUNET_HashCode *key)
+{
+  uint32_t *last_32;
+
+  GNUNET_CRYPTO_hash (domain_name,
+                     strlen (domain_name),
+                     key);
+  last_32 = (uint32_t *) key;
+  *last_32 ^= lock_number;
+}
+
+
+/**
+ * Hashmap iterator for matching a LockingRequest
+ *
+ * @param cls the LockingRequestMatch structure
+ * @param key current key code
+ * @param value value in the hash map (struct GNUNET_LOCKMANAGER_LockingRequest)
+ * @return GNUNET_YES if we should continue to
+ *         iterate,
+ *         GNUNET_NO if not. 
+ */
+static int
+match_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
+{
+  struct LockingRequestMatch *match = cls;
+  struct GNUNET_LOCKMANAGER_LockingRequest *lr = value;
+
+  if ( (match->lock == lr->lock) && (0 == strcmp (match->domain, lr->domain)) )
+  {
+    match->matched_entry = lr;    
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
+
+/**
+ * Function to find a LockingRequest associated with the given domain and lock
+ * attributes in the map
+ *
+ * @param map the map where the LockingRequests are stored
+ * @param domain the locking domain name
+ * @param lock the lock number
+ * @return the found LockingRequest; NULL if a matching LockingRequest wasn't
+ *           found 
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *
+hashmap_find_lockingrequest (const struct GNUNET_CONTAINER_MultiHashMap *map,
+                             const char *domain,
+                             uint32_t lock)
+{
+  struct GNUNET_HashCode hash;
+  struct LockingRequestMatch lock_match;
+
+  lock_match.matched_entry = NULL;
+  lock_match.domain = domain;
+  lock_match.lock = lock;
+  get_key (domain, lock, &hash);
+  GNUNET_CONTAINER_multihashmap_get_multiple (map,
+                                              &hash,
+                                              &match_iterator,
+                                              &lock_match);
+  return lock_match.matched_entry;
 }
 
 
@@ -151,126 +362,166 @@ 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);
-    }
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Calling status change for SUCCESS on lock num: %d, domain: %s\n",
+         r->lock, r->domain);
+    r->status_cb (r->status_cb_cls,
+                  r->domain,
+                  r->lock,
+                  r->status);
+  }
 }
 
 
 /**
- * Handler for server replies
+ * Function to generate acquire message for a lock
  *
- * @param cls the LOCKMANAGER_Handle
- * @param msg received message, NULL on timeout or fatal error
+ * @param domain_name the domain name of the lock
+ * @param lock the lock number
+ * @return the generated GNUNET_LOCKMANAGER_Message
  */
-static void 
-handle_replies (void *cls,
-                const struct GNUNET_MessageHeader *msg)
+static struct GNUNET_LOCKMANAGER_Message *
+generate_acquire_msg (const char *domain_name, uint32_t lock)
 {
-  struct GNUNET_LOCKMANAGER_Handle *handle = cls;
+  struct GNUNET_LOCKMANAGER_Message *msg;
+  size_t domain_name_len;
+  uint16_t  msg_size;
+  
+  domain_name_len = strlen (domain_name) + 1;
+  msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len;
+  msg = GNUNET_malloc (msg_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE);
+  msg->header.size = htons (msg_size);
+  msg->lock = htonl (lock);
+  memcpy (&msg[1], domain_name, domain_name_len);
+  return msg;
+}
 
-  if (NULL == msg)
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG,
-           "Lockmanager service not available or went down\n");
-      return;
-    }
-
-  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);
-    }
+
+/**
+ * Iterator to call relase on locks
+ *
+ * @param cls the lockmanager handle
+ * @param key current key code
+ * @param value the Locking request
+ * @return GNUNET_YES if we should continue to
+ *         iterate,
+ *         GNUNET_NO if not.
+ */
+static int
+release_n_retry_iterator (void *cls,
+                          const struct GNUNET_HashCode * key,
+                          void *value)
+{
+  struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
+  struct GNUNET_LOCKMANAGER_Handle *h = cls;
+  struct GNUNET_LOCKMANAGER_Message *msg;
+
+  msg = generate_acquire_msg (r->domain, r->lock);
+  queue_message (h, msg);
+  if (GNUNET_LOCKMANAGER_RELEASE == r->status)
+    return GNUNET_YES;
+  if (NULL != r->status_cb)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Calling status change for RELEASE on lock num: %d, domain: %s\n",
+         r->lock, r->domain);
+    r->status = GNUNET_LOCKMANAGER_RELEASE;
+    r->status_cb (r->status_cb_cls,
+                  r->domain,
+                  r->lock,
+                  GNUNET_LOCKMANAGER_RELEASE);
+  }
+  return GNUNET_YES;
 }
 
 
 /**
- * Transmit notify for sending message to server
+ * Handler for server replies
  *
- * @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
+ * @param cls the LOCKMANAGER_Handle
+ * @param msg received message, NULL on timeout or fatal error
  */
-static size_t 
-transmit_notify (void *cls, size_t size, void *buf)
+static void 
+handle_replies (void *cls,
+                const struct GNUNET_MessageHeader *msg)
 {
-  struct GNUNET_LOCKMANAGER_Message *msg = cls;
-  uint16_t msg_size;
+  struct GNUNET_LOCKMANAGER_Handle *handle = cls;
+  const struct GNUNET_LOCKMANAGER_Message *m;
+  struct GNUNET_LOCKMANAGER_LockingRequest *lr;
+  const char *domain;
+  struct GNUNET_HashCode hash;
+  uint32_t lock;
+  uint16_t msize;
 
-  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);
+  handle->in_replies = GNUNET_NO;
+  if (NULL == msg)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Lockmanager service not available or went down\n");    
+    /* Should release all locks and retry to acquire them */
+    GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
+                                           &release_n_retry_iterator,
+                                           handle);
+    return;
+  }
+  GNUNET_CLIENT_receive (handle->conn,
+                         &handle_replies,
+                         handle,
+                         GNUNET_TIME_UNIT_FOREVER_REL);
+  handle->in_replies = GNUNET_YES;
+  if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type))
+  {
+    GNUNET_break (0);
+    return;
+  }
+  msize = ntohs (msg->size);
+  if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message))
+  {
+    GNUNET_break (0);
+    return;
+  }
+  m = (const struct GNUNET_LOCKMANAGER_Message *) msg;
+  domain = (const char *) &m[1];
+  msize -= sizeof (struct GNUNET_LOCKMANAGER_Message);
+  if ('\0' != domain[msize-1])
+  {
+    GNUNET_break (0);
+    return;
+  }
+
+  lock = ntohl (m->lock);
+  get_key (domain, lock, &hash);      
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Message of size %u sent\n", msg_size);
-  return msg_size;
+       "Received SUCCESS message for lock: %d, domain %s\n",
+       lock, domain);
+  if (NULL == (lr = hashmap_find_lockingrequest (handle->hashmap,
+                                                 domain,
+                                                 lock)))
+  {
+    GNUNET_break (0);
+    return;
+  }
+  if (GNUNET_LOCKMANAGER_SUCCESS == lr->status)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Changing status for lock: %d in domain: %s to SUCCESS\n",
+       lr->lock, lr->domain);
+  lr->status = GNUNET_LOCKMANAGER_SUCCESS;
+  GNUNET_SCHEDULER_add_continuation (&call_status_cb_task,
+                                     lr,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 /**
  * Iterator to free hash map entries.
  *
- * @param cls NULL
+ * @param cls the lockmanger handle
  * @param key current key code
  * @param value the Locking request
  * @return GNUNET_YES if we should continue to
@@ -279,13 +530,18 @@ transmit_notify (void *cls, size_t size, void *buf)
  */
 static int
 free_iterator(void *cls,
-              const GNUNET_HashCode * key,
+              const struct GNUNET_HashCode * key,
               void *value)
 {
+  struct GNUNET_LOCKMANAGER_Handle *h = cls;
   struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Clearing locking request\n");
+  GNUNET_assert (GNUNET_YES == 
+                 GNUNET_CONTAINER_multihashmap_remove (h->hashmap,
+                                                       key,
+                                                       value));
   GNUNET_free (r->domain);
   GNUNET_free (r);
   return GNUNET_YES;
@@ -313,20 +569,18 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
   h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle));
   h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg);
   if (NULL == h->conn)
-    {
-      GNUNET_free (h);
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
-      return NULL;
-    }
-  
+  {
+    GNUNET_free (h);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+    return NULL;
+  }  
   h->hashmap = GNUNET_CONTAINER_multihashmap_create (15);
   GNUNET_assert (NULL != h->hashmap);
-
   GNUNET_CLIENT_receive (h->conn,
                          &handle_replies,
                          h,
                          GNUNET_TIME_UNIT_FOREVER_REL);
-  
+  h->in_replies = GNUNET_YES;
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
   return h;
 }
@@ -340,20 +594,35 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
 void
 GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle)
 {
+  struct MessageQueue *head;
+
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
-  GNUNET_CLIENT_disconnect (handle->conn);
-  
   if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap))
-    {
-      LOG (GNUNET_ERROR_TYPE_WARNING,
-           "Some locking requests are still present. Cancel them before "
-           "calling %s\n", __func__);
-      GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
-                                             &free_iterator,
-                                             NULL);
-    }
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Some locking requests are still present. Cancel them before "
+         "calling %s\n", __func__);
+    GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
+                                           &free_iterator,
+                                           handle);
+  }
   GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap);
-
+  /* Clear the message queue */
+  if (NULL != handle->transmit_handle)
+  {
+    GNUNET_CLIENT_notify_transmit_ready_cancel (handle->transmit_handle);
+  }
+  head = handle->mq_head;
+  while (NULL != head)
+  {
+    GNUNET_CONTAINER_DLL_remove (handle->mq_head,
+                                 handle->mq_tail,
+                                 head);
+    GNUNET_free (head->msg);
+    GNUNET_free (head);
+    head = handle->mq_head;
+  }
+  GNUNET_CLIENT_disconnect (handle->conn);
   GNUNET_free (handle);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
 }
@@ -380,8 +649,7 @@ GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle)
  *
  * @param status_cb_cls the closure to the above callback
  *
- * @return the locking request handle for this request. It will be invalidated
- *           when status_cb is called.
+ * @return the locking request handle for this request
  */
 struct GNUNET_LOCKMANAGER_LockingRequest *
 GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
@@ -394,43 +662,26 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
   struct GNUNET_LOCKMANAGER_LockingRequest *r;
   struct GNUNET_LOCKMANAGER_Message *msg;
   struct GNUNET_HashCode hash;
-  uint16_t msg_size;
+  size_t domain_name_length;
   
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
   r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest));
-  r->domain_name_length = strlen (domain_name) + 1;
+  domain_name_length = strlen (domain_name) + 1;
   r->handle = handle;
   r->lock = lock;
-  r->domain = GNUNET_malloc (r->domain_name_length);
+  r->domain = GNUNET_malloc (domain_name_length);
   r->status = GNUNET_LOCKMANAGER_RELEASE;
   r->status_cb = status_cb;
   r->status_cb_cls = status_cb_cls;
-  memcpy (r->domain, domain_name, r->domain_name_length);
-  
-  msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length;
-  msg = GNUNET_malloc (msg_size);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE);
-  msg->header.size = htons (msg_size);
-  msg->lock = htonl (lock);
-  memcpy (&msg[1], r->domain, r->domain_name_length);
-  
+  memcpy (r->domain, domain_name, domain_name_length);
+  msg = generate_acquire_msg (r->domain, r->lock);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n");
-  r->transmit_handle =
-    GNUNET_CLIENT_notify_transmit_ready (r->handle->conn,
-                                         msg_size,
-                                         TIMEOUT,
-                                         GNUNET_YES,
-                                         &transmit_notify,
-                                         msg);
-  hash_domain_and_lock (r->domain,
-                        r->domain_name_length,
-                        r->lock,
-                        &hash);
+  queue_message (handle, msg);
+  get_key (r->domain, r->lock, &hash);
   GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap,
                                      &hash,
                                      r,
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
   return r;
 }
@@ -439,8 +690,8 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
 
 /**
  * Function to cancel the locking request generated by
- * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired us then the lock is
- * released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any
+ * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired by us then the lock
+ * is released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any
  * status changes resulting due to this call.
  *
  * @param request the LockingRequest to cancel
@@ -449,40 +700,29 @@ void
 GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
                                    *request)
 {
+  struct GNUNET_LOCKMANAGER_Message *msg;
   struct GNUNET_HashCode hash;
+  uint16_t msg_size;
+  size_t domain_name_length;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
   /* FIXME: Stop ACQUIRE retransmissions */
   if (GNUNET_LOCKMANAGER_SUCCESS == request->status)
-    {
-      struct GNUNET_LOCKMANAGER_Message *msg;
-      uint16_t msg_size;
-
-      msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) 
-        + request->domain_name_length;
-      msg = GNUNET_malloc (msg_size);
-      msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE);
-      msg->header.size = htons (msg_size);
-      msg->lock = htonl (request->lock);
-      memcpy (&msg[1], request->domain, request->domain_name_length);
-      
-      GNUNET_CLIENT_notify_transmit_ready (request->handle->conn,
-                                           msg_size,
-                                           TIMEOUT, /* What if this fails */
-                                           GNUNET_NO,
-                                           &transmit_notify,
-                                           msg);
-    }
-    
-  hash_domain_and_lock (request->domain,
-                        request->domain_name_length,
-                        request->lock,
-                        &hash);
-
+  {
+    domain_name_length = strlen (request->domain) + 1;
+    msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) 
+      + domain_name_length;
+    msg = GNUNET_malloc (msg_size);
+    msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE);
+    msg->header.size = htons (msg_size);
+    msg->lock = htonl (request->lock);
+    memcpy (&msg[1], request->domain, domain_name_length);
+    queue_message (request->handle, msg);
+  }
+  get_key (request->domain, request->lock, &hash);
   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__);