-docu, style fixes
[oweals/gnunet.git] / src / util / client_manager.c
index c415ce8454a64fcd00cab697b4b25e36bb6cb8f6..6a462cad66638a2d26fa3d75b4a5be1c51861935 100644 (file)
@@ -30,7 +30,7 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-client-mgr", __VA_ARGS__)
 
 
 /**
@@ -93,6 +93,16 @@ struct GNUNET_CLIENT_MANAGER_Connection
    */
   const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers;
 
+  /**
+   * Disconnect callback.
+   */
+  void (*disconnect_cb)(void *);
+
+  /**
+   * Disconnect closure.
+   */
+  void *disconnect_cls;
+
   /**
    * User context value.
    * @see GNUNET_CLIENT_MANAGER_set_user_context()
@@ -109,7 +119,7 @@ struct GNUNET_CLIENT_MANAGER_Connection
   /**
    * Task doing exponential back-off trying to reconnect.
    */
-  GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
+  struct GNUNET_SCHEDULER_Task * reconnect_task;
 
   /**
    * Time for next connect retry.
@@ -125,7 +135,7 @@ struct GNUNET_CLIENT_MANAGER_Connection
    * #GNUNET_YES if GNUNET_CLIENT_MANAGER_disconnect() was called
    * and we're transmitting the last messages from the queue.
    */
-  uint8_t disconnecting;
+  uint8_t is_disconnecting;
 };
 
 
@@ -185,12 +195,24 @@ static void
 transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr);
 
 
+static void
+schedule_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
+  GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO,
+                                    mgr->disconnect_cb, mgr->disconnect_cls);
+}
+
+
 /**
  * Transmit next message to service.
  *
- * @param cls  The struct GNUNET_PSYC_Channel.
- * @param size Number of bytes available in @a buf.
- * @param buf  Where to copy the message.
+ * @param cls
+ *        struct GNUNET_CLIENT_MANAGER_Connection
+ * @param size
+ *        Number of bytes available in @a buf.
+ * @param buf
+ *        Where to copy the message.
  *
  * @return Number of bytes copied to @a buf.
  */
@@ -221,7 +243,14 @@ send_next_message (void *cls, size_t buf_size, void *buf)
   GNUNET_free (mqi);
 
   if (NULL != mgr->tmit_head)
+  {
     transmit_next (mgr);
+  }
+  else if (GNUNET_YES == mgr->is_disconnecting)
+  {
+    GNUNET_SCHEDULER_add_now (&schedule_disconnect, mgr);
+    return size;
+  }
 
   if (GNUNET_NO == mgr->in_receive)
   {
@@ -247,8 +276,9 @@ transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
 
   if (NULL == mgr->tmit_head)
   {
-    if (GNUNET_YES == mgr->disconnecting)
-      GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO);
+    if (GNUNET_YES == mgr->is_disconnecting)
+      GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO,
+                                        mgr->disconnect_cb, mgr->disconnect_cls);
     return;
   }
 
@@ -265,14 +295,16 @@ transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
 /**
  * Try again to connect to the service.
  *
- * @param cls Channel handle.
- * @param tc Scheduler context.
+ * @param cls
+ *        Channel handle.
+ * @param tc
+ *        Scheduler context.
  */
 static void
-reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+schedule_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
-  mgr->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
+  mgr->reconnect_task = NULL;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Connecting to %s service.\n", mgr->service_name);
@@ -287,9 +319,12 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 /**
  * Connect to service.
  *
- * @param cfg           Configuration to use.
- * @param service_name  Service name to connect to.
- * @param handlers      Message handlers.
+ * @param cfg
+ *        Configuration to use.
+ * @param service_name
+ *        Service name to connect to.
+ * @param handlers
+ *        Message handlers.
  *
  * @return Client manager connection handle.
  */
@@ -305,7 +340,7 @@ GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
   mgr->service_name = service_name;
   mgr->handlers = handlers;
   mgr->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
-  mgr->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, mgr);
+  mgr->reconnect_task = GNUNET_SCHEDULER_add_now (&schedule_reconnect, mgr);
   return mgr;
 }
 
@@ -313,19 +348,31 @@ GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
 /**
  * Disconnect from the service.
  *
- * @param mgr             Client manager connection.
- * @param transmit_queue  Transmit pending messages in queue before disconnecting.
+ * @param mgr
+ *        Client manager connection.
+ * @param transmit_queue
+ *        Transmit pending messages in queue before disconnecting.
+ * @param disconnect_cb
+ *        Function called after disconnected from the service.
+ * @param cls
+ *        Closure for @a disconnect_cb.
  */
 void
 GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
-                                  int transmit_queue)
+                                  int transmit_queue,
+                                  GNUNET_ContinuationCallback disconnect_cb,
+                                  void *cls)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting (%d)\n", transmit_queue);
+  mgr->disconnect_cb = disconnect_cb;
+  mgr->disconnect_cls = cls;
   if (NULL != mgr->tmit_head)
   {
     if (GNUNET_YES == transmit_queue)
     {
-      mgr->disconnecting = GNUNET_YES;
+      mgr->is_disconnecting = GNUNET_YES;
       transmit_next (mgr);
+      return;
     }
     else
     {
@@ -335,10 +382,10 @@ GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
       GNUNET_CLIENT_MANAGER_drop_queue (mgr);
     }
   }
-  if (mgr->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
+  if (mgr->reconnect_task != NULL)
   {
     GNUNET_SCHEDULER_cancel (mgr->reconnect_task);
-    mgr->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
+    mgr->reconnect_task = NULL;
   }
   if (NULL != mgr->client_tmit)
   {
@@ -350,19 +397,23 @@ GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
     GNUNET_CLIENT_disconnect (mgr->client);
     mgr->client = NULL;
   }
+  if (NULL != mgr->disconnect_cb)
+    mgr->disconnect_cb (mgr->disconnect_cls);
   GNUNET_free (mgr);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnected.\n");
 }
 
 
 /**
  * Reschedule connect to the service using exponential back-off.
  *
- * @param mgr  Client manager connection.
+ * @param mgr
+ *        Client manager connection.
  */
 void
 GNUNET_CLIENT_MANAGER_reconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
 {
-  if (GNUNET_SCHEDULER_NO_TASK != mgr->reconnect_task)
+  if (NULL != mgr->reconnect_task)
     return;
 
   if (NULL != mgr->client_tmit)
@@ -380,7 +431,7 @@ GNUNET_CLIENT_MANAGER_reconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
        "Scheduling task to reconnect to service in %s.\n",
        GNUNET_STRINGS_relative_time_to_string (mgr->reconnect_delay, GNUNET_YES));
   mgr->reconnect_task =
-      GNUNET_SCHEDULER_add_delayed (mgr->reconnect_delay, &reconnect, mgr);
+    GNUNET_SCHEDULER_add_delayed (mgr->reconnect_delay, &schedule_reconnect, mgr);
   mgr->reconnect_delay = GNUNET_TIME_STD_BACKOFF (mgr->reconnect_delay);
 }
 
@@ -388,8 +439,11 @@ GNUNET_CLIENT_MANAGER_reconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
 /**
  * Add a message to the end of the transmission queue.
  *
- * @param mgr  Client manager connection.
- * @param msg  Message to transmit.  It is free()'d after transmission.
+ * @param mgr
+ *        Client manager connection.
+ * @param msg
+ *        Message to transmit, should be allocated with GNUNET_malloc() or
+ *        GNUNET_new(), as it is freed with GNUNET_free() after transmission.
  */
 void
 GNUNET_CLIENT_MANAGER_transmit (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
@@ -405,8 +459,11 @@ GNUNET_CLIENT_MANAGER_transmit (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
 /**
  * Add a message to the beginning of the transmission queue.
  *
- * @param mgr  Client manager connection.
- * @param msg  Message to transmit.  It is free()'d after transmission.
+ * @param mgr
+ *        Client manager connection.
+ * @param msg
+ *        Message to transmit, should be allocated with GNUNET_malloc() or
+ *        GNUNET_new(), as it is freed with GNUNET_free() after transmission.
  */
 void
 GNUNET_CLIENT_MANAGER_transmit_now (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
@@ -422,7 +479,8 @@ GNUNET_CLIENT_MANAGER_transmit_now (struct GNUNET_CLIENT_MANAGER_Connection *mgr
 /**
  * Drop all queued messages.
  *
- * @param mgr  Client manager connection.
+ * @param mgr
+ *        Client manager connection.
  */
 void
 GNUNET_CLIENT_MANAGER_drop_queue (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
@@ -441,7 +499,8 @@ GNUNET_CLIENT_MANAGER_drop_queue (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
 /**
  * Obtain client connection handle.
  *
- * @param mgr  Client manager connection handle.
+ * @param mgr
+ *        Client manager connection.
  *
  * @return Client connection handle.
  */
@@ -456,8 +515,11 @@ GNUNET_CLIENT_MANAGER_get_client (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
  * Return user context associated with the given client.
  * Note: you should probably use the macro (call without the underscore).
  *
- * @param mgr  Client manager connection.
- * @param size Number of bytes in user context struct (for verification only).
+ * @param mgr
+ *        Client manager connection.
+ * @param size
+ *        Number of bytes in user context struct (for verification only).
+ *
  * @return User context.
  */
 void *
@@ -476,9 +538,12 @@ GNUNET_CLIENT_MANAGER_get_user_context_ (struct GNUNET_CLIENT_MANAGER_Connection
  * Set user context to be associated with the given client.
  * Note: you should probably use the macro (call without the underscore).
  *
- * @param mgr  Client manager connection.
- * @param ctx  User context.
- * @param size Number of bytes in user context struct (for verification only).
+ * @param mgr
+ *        Client manager connection.
+ * @param ctx
+ *        User context.
+ * @param size
+ *        Number of bytes in user context struct (for verification only).
  */
 void
 GNUNET_CLIENT_MANAGER_set_user_context_ (struct GNUNET_CLIENT_MANAGER_Connection *mgr,