gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r21367 - gnunet/src/lockmanager


From: gnunet
Subject: [GNUnet-SVN] r21367 - gnunet/src/lockmanager
Date: Wed, 9 May 2012 10:29:17 +0200

Author: harsha
Date: 2012-05-09 10:29:17 +0200 (Wed, 09 May 2012)
New Revision: 21367

Modified:
   gnunet/src/lockmanager/gnunet-service-lockmanager.c
Log:
lock acquire and release

Modified: gnunet/src/lockmanager/gnunet-service-lockmanager.c
===================================================================
--- gnunet/src/lockmanager/gnunet-service-lockmanager.c 2012-05-09 07:09:30 UTC 
(rev 21366)
+++ gnunet/src/lockmanager/gnunet-service-lockmanager.c 2012-05-09 08:29:17 UTC 
(rev 21367)
@@ -82,11 +82,6 @@
   struct LockList *prev;
 
   /**
-   * The client whizch is currently holding this lock
-   */
-  struct GNUNET_SERVER_Client *client;
-
-  /**
    * List head of clients waiting for this lock
    */
   struct WaitList *wait_list_head;
@@ -97,6 +92,11 @@
   struct WaitList *wait_list_tail;
 
   /**
+   * The client which is currently holding this lock
+   */
+  struct GNUNET_SERVER_Client *client;
+
+  /**
    * The name of the locking domain this lock belongs to
    */
   char *domain_name;
@@ -151,7 +151,6 @@
 static struct ClientList *cl_tail;
 
 
-
 /**
  * Function to search for a lock in lock_list matching the given domain_name 
and
  * lock number
@@ -164,8 +163,8 @@
  */
 static int
 ll_find_lock (const char *domain_name,
-           const uint32_t lock_num,
-           struct LockList **ret)
+              const uint32_t lock_num,
+              struct LockList **ret)
 {
   struct LockList *current_lock;
 
@@ -176,14 +175,49 @@
       if ( (0 == strcmp (domain_name, current_lock->domain_name))
            && (lock_num == current_lock->lock_num))
         {
-          *ret = current_lock;
+          if (NULL != ret)
+            *ret = current_lock;
           return GNUNET_YES;
         }
 
       current_lock = current_lock->next;
     }
+  if (NULL != ret)
+    *ret = current_lock;
+  return GNUNET_NO;
+}
+
+
+/**
+ * Function to search for a lock in lock_list matching the given domain_name 
and
+ * lock number
+ *
+ * @param client the client owning this lock currently
+ * @param ret this will be the pointer to the corresponding Lock if found; else
+ *         it will be the last element in the locks list
+ * @return GNUNET_YES if a matching lock is present in lock_list; GNUNET_NO if 
not
+ */
+static int
+ll_find_lock_by_owner (const struct GNUNET_SERVER_Client *client,
+                       struct LockList **ret)
+{
+  struct LockList *current_lock;
+
+  current_lock = ll_head;
   
-  *ret = current_lock;
+  while (NULL != current_lock)
+    {
+      if (client == current_lock->client)
+        {
+          if (NULL != ret)
+            *ret = current_lock;
+          return GNUNET_YES;
+        }
+
+      current_lock = current_lock->next;
+    }
+  if (NULL != ret)
+    *ret = current_lock;
   return GNUNET_NO;
 }
 
@@ -191,22 +225,29 @@
 /**
  * Function to append a lock to the global lock list
  *
+ * @param client the client which currently owns this lock
  * @param domain_name the name of the locking domain
- * @param domain_name_len the length of the domain name
  * @param lock_num the number of the lock
  * @param tail the pointer to the tail of the global lock list
  */
 static void
-ll_add_lock (const char *domain_name,
-          size_t domain_name_len,
-          const uint32_t lock_num)
+ll_add_lock (struct GNUNET_SERVER_Client *client,
+             const char *domain_name,
+             const uint32_t lock_num)
 {
   struct LockList *lock;
+  size_t domain_name_len;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Adding a lock with num: %u and domain: %s to lock list\n",
+       lock_num, domain_name);
+
   lock = GNUNET_malloc (sizeof (struct LockList));
+  domain_name_len = strlen (domain_name) + 1;
   lock->domain_name = GNUNET_malloc (domain_name_len);
   strncpy (lock->domain_name, domain_name, domain_name_len);
   lock->lock_num = lock_num;
+  lock->client = client;
   
   GNUNET_CONTAINER_DLL_insert_tail (ll_head,
                                     ll_tail,
@@ -222,6 +263,9 @@
 static void
 ll_remove_lock (struct LockList *lock)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Removing lock with num: %u, domain: %s\n",
+       lock->lock_num, lock->domain_name);
   GNUNET_assert (NULL != ll_head);
   GNUNET_CONTAINER_DLL_remove (ll_head,
                                ll_tail,
@@ -252,18 +296,20 @@
     {
       if (client == current_wl_entry->client)
         {
-          *ret = current_wl_entry;
+          if (NULL != ret)
+            *ret = current_wl_entry;
           return GNUNET_YES;
         }
       current_wl_entry = current_wl_entry->next;
     }
-  *ret = current_wl_entry;
+  if (NULL != ret)
+    *ret = current_wl_entry;
   return GNUNET_NO;
 }
 
 
 /**
- * Add a client to the wait list of a lock
+ * Add a client to the wait list of given lock
  *
  * @param lock the lock list entry of a lock
  * @param client the client to queue for the lock's wait list
@@ -274,6 +320,12 @@
 {
   struct WaitList *wl_entry;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Adding a client to lock's wait list\n"
+       "\t lock num: %u, domain: %s\n",
+       lock->lock_num,
+       lock->domain_name);
+
   wl_entry = GNUNET_malloc (sizeof (struct WaitList));
   wl_entry->client = client;
   GNUNET_CONTAINER_DLL_insert_tail (lock->wait_list_head,
@@ -282,6 +334,12 @@
 }
 
 
+/**
+ * Remove a client from the wait list of the given lock
+ *
+ * @param lock the lock list entry of the lock
+ * @param wl_client the wait list entry to be removed
+ */
 static void
 ll_wl_remove_client (struct LockList *lock,
                      struct WaitList *wl_client)
@@ -314,14 +372,16 @@
     {
       if (client == current->client)
         {
-          *ret = current;
+          if (NULL != ret) 
+            *ret = current;
           return GNUNET_YES;
         }
 
       current = current->next;
     }
   
-  *ret = current;
+  if (NULL != ret)
+    *ret = current;
   return GNUNET_NO;
 }
 
@@ -335,8 +395,12 @@
 cl_add_client (struct GNUNET_SERVER_Client *client)
 {
   struct ClientList *new_client;
+  
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Adding a client to the client list\n");
 
   new_client = GNUNET_malloc (sizeof (struct ClientList));
+  GNUNET_SERVER_client_keep (client);
   new_client->client = client;
   GNUNET_CONTAINER_DLL_insert_tail (cl_head,
                                     cl_tail,
@@ -352,6 +416,9 @@
 static void
 cl_remove_client (struct ClientList *client)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Removing a client from the client list\n");
+  GNUNET_SERVER_client_drop (client->client);
   GNUNET_CONTAINER_DLL_remove (cl_head,
                                cl_tail,
                                client);
@@ -389,6 +456,37 @@
 
 
 /**
+ * Send SUCCESS message to the client
+ *
+ * @param client the client to which the message has to be sent
+ * @param domain_name the locking domain of the successfully acquried lock
+ * @param lock_num the number of the successfully acquired lock
+ */
+static void
+send_success_msg (struct GNUNET_SERVER_Client *client,
+                  const char *domain_name,
+                  int lock_num)
+{
+  struct GNUNET_LOCKMANAGER_Message *reply;
+  size_t domain_name_len;
+  uint16_t reply_size;
+
+  domain_name_len = strlen (domain_name) + 1;
+  reply_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len;
+  reply = GNUNET_malloc (reply_size);
+  reply->header.size = htons (reply_size);
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS);
+  reply->lock = htonl (lock_num);
+  strncpy ((char *) &reply[1], domain_name, domain_name_len);
+  GNUNET_SERVER_notify_transmit_ready (client,
+                                       reply_size,
+                                       TIMEOUT,
+                                       &transmit_notify,
+                                       reply);
+}
+
+
+/**
  * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE
  *
  * @param cls NULL
@@ -401,26 +499,36 @@
                 const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_LOCKMANAGER_Message *request;
-  struct GNUNET_LOCKMANAGER_Message *reply;
-  int16_t request_size;
+  const char *domain_name;
+  struct LockList *ll_entry;
+  uint32_t lock_num;
   
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received an ACQUIRE message\n");
+
+
+  /* Check if the client is in client list */
+  if (GNUNET_NO == cl_find_client (client, NULL))
+    {
+      cl_add_client (client);
+    }
   
   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);
-
+  lock_num = ntohl (request->lock);
+  domain_name = (char *) &request[1];
+  if (GNUNET_YES == ll_find_lock (domain_name,
+                                  lock_num,
+                                  &ll_entry))
+    {/* Add client to the lock's wait list */
+      ll_wl_add_client (ll_entry, client);
+    }
+  else
+    {
+      ll_add_lock (client, domain_name, lock_num);
+      send_success_msg (client, domain_name, lock_num);
+    }
+  
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -437,14 +545,75 @@
                 struct GNUNET_SERVER_Client *client,
                 const struct GNUNET_MessageHeader *message)
 {
+  const struct GNUNET_LOCKMANAGER_Message *request;
+  const char *domain_name;
+  struct LockList *ll_entry;
+  uint32_t lock_num;
+
+  request = (struct GNUNET_LOCKMANAGER_Message *) message;
+  lock_num = ntohl (request->lock);
+  domain_name = (char *) &request[1];
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Received a RELEASE message\n");
-
+       "Received a RELEASE message on lock with num: %d, domain: %s\n",
+       lock_num, domain_name);
+  if (GNUNET_YES == ll_find_lock (domain_name, lock_num, &ll_entry))
+    {
+      if (NULL == ll_entry->wait_list_head)
+        {
+          ll_remove_lock (ll_entry);
+        }
+      else
+        {
+          /* Do furthur processing on lock's wait list here */
+        }
+    }
+  else
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "\t give lock doesn't exist\n");
+    }
+  
+  
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
 
 /**
+ * Callback for client disconnect
+ *
+ * @param cls NULL
+ * @param client the client which has disconnected
+ */
+static void
+client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
+{
+  struct ClientList *cl_entry;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "A client has been disconnected -- freeing its locks and resources\n");
+  
+  if (GNUNET_YES == cl_find_client (client, &cl_entry))
+    {
+      struct LockList *lock;
+      
+      cl_remove_client (cl_entry);
+      while (GNUNET_YES == ll_find_lock_by_owner (client, &lock))
+        {
+          if (NULL == lock->wait_list_head)
+            {
+              ll_remove_lock (lock);
+            }
+          else
+            {
+              /* Do furthur processing on lock's wait list here */
+            }
+        }
+    }
+  else GNUNET_break (0);
+}
+
+
+/**
  * Lock manager setup
  *
  * @param cls closure
@@ -466,6 +635,10 @@
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lockmanager\n");
   GNUNET_SERVER_add_handlers (server,
                               message_handlers);
+  GNUNET_SERVER_disconnect_notify (server,
+                                   &client_disconnect_cb,
+                                   NULL);
+                                   
   
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]