gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r35716 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r35716 - in gnunet/src: include util
Date: Thu, 7 May 2015 14:15:33 +0200

Author: tg
Date: 2015-05-07 14:15:32 +0200 (Thu, 07 May 2015)
New Revision: 35716

Modified:
   gnunet/src/include/gnunet_client_manager_lib.h
   gnunet/src/include/gnunet_common.h
   gnunet/src/util/client_manager.c
Log:
client_manager: add API for async operations

Modified: gnunet/src/include/gnunet_client_manager_lib.h
===================================================================
--- gnunet/src/include/gnunet_client_manager_lib.h      2015-05-07 12:15:24 UTC 
(rev 35715)
+++ gnunet/src/include/gnunet_client_manager_lib.h      2015-05-07 12:15:32 UTC 
(rev 35716)
@@ -249,6 +249,97 @@
   GNUNET_CLIENT_MANAGER_set_user_context_ (mgr, ctx, sizeof (*ctx))
 
 
+/**
+ * Get a unique operation ID to distinguish between asynchronous requests.
+ *
+ * @param mgr
+ *        Client manager connection.
+ *
+ * @return Operation ID to use.
+ */
+uint64_t
+GNUNET_CLIENT_MANAGER_op_get_next_id (struct GNUNET_CLIENT_MANAGER_Connection 
*mgr);
+
+
+/**
+ * Find operation by ID.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID to look up.
+ * @param[out] result_cb
+ *        If an operation was found, its result callback is returned here.
+ * @param[out] cls
+ *        If an operation was found, its closure is returned here.
+ *
+ * @return #GNUNET_YES if an operation was found,
+ *         #GNUNET_NO  if not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_find (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                               uint64_t op_id,
+                               GNUNET_ResultCallback *result_cb,
+                               void **cls);
+
+
+/**
+ * Add a new operation.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param result_cb
+ *        Function to call with the result of the operation.
+ * @param cls
+ *        Closure for @a result_cb.
+ *
+ * @return ID of the new operation.
+ */
+uint64_t
+GNUNET_CLIENT_MANAGER_op_add (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                              GNUNET_ResultCallback result_cb,
+                              void *cls);
+
+
+/**
+ * Call the result callback and remove the operation.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID.
+ * @param result_code
+ *        Result of the operation.
+ * @param data
+ *        Data result of the operation.
+ * @param data_size
+ *        Size of @a data.
+ *
+ * @return #GNUNET_YES if the operation was found and removed,
+ *         #GNUNET_NO  if the operation was not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_result (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                                 uint64_t op_id, int64_t result_code,
+                                 const void *data, uint16_t data_size);
+
+
+/**
+ * Cancel an operation.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID.
+ *
+ * @return #GNUNET_YES if the operation was found and removed,
+ *         #GNUNET_NO  if the operation was not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_cancel (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                                 uint64_t op_id);
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: gnunet/src/include/gnunet_common.h
===================================================================
--- gnunet/src/include/gnunet_common.h  2015-05-07 12:15:24 UTC (rev 35715)
+++ gnunet/src/include/gnunet_common.h  2015-05-07 12:15:32 UTC (rev 35716)
@@ -248,6 +248,29 @@
 
 };
 
+
+/**
+ * Answer from service to client about last operation.
+ */
+struct GNUNET_OperationResultMessage
+{
+  struct GNUNET_MessageHeader header;
+
+  uint32_t reserved GNUNET_PACKED;
+
+  /**
+   * Operation ID.
+   */
+  uint64_t op_id GNUNET_PACKED;
+
+  /**
+   * Status code for the operation.
+   */
+  uint64_t result_code GNUNET_PACKED;
+
+  /* Followed by data. */
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 /**
@@ -273,6 +296,23 @@
 (*GNUNET_ContinuationCallback) (void *cls);
 
 
+/**
+ * Function called with the result of an asynchronous operation.
+ *
+ * @param cls
+ *        Closure.
+ * @param result_code
+ *        Result code for the operation.
+ * @param data
+ *        Data result for the operation.
+ * @param data_size
+ *        Size of @a data.
+ */
+typedef void
+(*GNUNET_ResultCallback) (void *cls, int64_t result_code,
+                          const void *data, uint16_t data_size);
+
+
 /* ****************************** logging ***************************** */
 
 /**

Modified: gnunet/src/util/client_manager.c
===================================================================
--- gnunet/src/util/client_manager.c    2015-05-07 12:15:24 UTC (rev 35715)
+++ gnunet/src/util/client_manager.c    2015-05-07 12:15:32 UTC (rev 35716)
@@ -33,6 +33,28 @@
 #define LOG(kind,...) GNUNET_log_from (kind, "util-client-mgr", __VA_ARGS__)
 
 
+struct OperationListItem
+{
+  struct OperationListItem *prev;
+  struct OperationListItem *next;
+
+  /**
+   * Operation ID.
+   */
+  uint64_t op_id;
+
+  /**
+   * Continuation to invoke with the result of an operation.
+   */
+  GNUNET_ResultCallback result_cb;
+
+  /**
+   * Closure for @a result_cb.
+   */
+  void *cls;
+};
+
+
 /**
  * List of arrays of message handlers.
  */
@@ -94,6 +116,21 @@
   const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers;
 
   /**
+   * First operation in the linked list.
+   */
+  struct OperationListItem *op_head;
+
+  /**
+   * Last operation in the linked list.
+   */
+  struct OperationListItem *op_tail;
+
+  /**
+   * Last operation ID used.
+   */
+  uint64_t last_op_id;
+
+  /**
    * Disconnect callback.
    */
   void (*disconnect_cb)(void *);
@@ -559,3 +596,204 @@
   mgr->user_ctx_size = size;
   mgr->user_ctx = ctx;
 }
+
+
+/**
+ * Get a unique operation ID to distinguish between asynchronous requests.
+ *
+ * @param mgr
+ *        Client manager connection.
+ *
+ * @return Operation ID to use.
+ */
+uint64_t
+GNUNET_CLIENT_MANAGER_op_get_next_id (struct GNUNET_CLIENT_MANAGER_Connection 
*mgr)
+{
+  return ++mgr->last_op_id;
+}
+
+
+/**
+ * Find operation by ID.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID to look up.
+ *
+ * @return Operation, or NULL if not found.
+ */
+static struct OperationListItem *
+op_find (struct GNUNET_CLIENT_MANAGER_Connection *mgr, uint64_t op_id)
+{
+  struct OperationListItem *op = mgr->op_head;
+  while (NULL != op)
+  {
+    if (op->op_id == op_id)
+      return op;
+    op = op->next;
+  }
+  return NULL;
+}
+
+
+/**
+ * Find operation by ID.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID to look up.
+ * @param[out] result_cb
+ *        If an operation was found, its result callback is returned here.
+ * @param[out] cls
+ *        If an operation was found, its closure is returned here.
+ *
+ * @return #GNUNET_YES if an operation was found,
+ *         #GNUNET_NO  if not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_find (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                               uint64_t op_id,
+                               GNUNET_ResultCallback *result_cb,
+                               void **cls)
+{
+  struct OperationListItem *op = op_find (mgr, op_id);
+  if (NULL != op)
+  {
+    *result_cb = op->result_cb;
+    *cls = op->cls;
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+
+/**
+ * Add a new operation.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param result_cb
+ *        Function to call with the result of the operation.
+ * @param cls
+ *        Closure for @a result_cb.
+ *
+ * @return ID of the new operation.
+ */
+uint64_t
+GNUNET_CLIENT_MANAGER_op_add (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                              GNUNET_ResultCallback result_cb,
+                              void *cls)
+{
+  if (NULL == result_cb)
+    return 0;
+
+  struct OperationListItem *op = GNUNET_malloc (sizeof (*op));
+  op->op_id = GNUNET_CLIENT_MANAGER_op_get_next_id (mgr);
+  op->result_cb = result_cb;
+  op->cls = cls;
+  GNUNET_CONTAINER_DLL_insert_tail (mgr->op_head, mgr->op_tail, op);
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "%p Added operation #%" PRIu64 "\n", mgr, op->op_id);
+  return op->op_id;
+}
+
+
+/**
+ * Remove an operation, and call its result callback (unless it was cancelled).
+ *
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID.
+ * @param result_code
+ *        Result of the operation.
+ * @param data
+ *        Data result of the operation.
+ * @param data_size
+ *        Size of @a data.
+ * @param cancel
+ *        Is the operation cancelled?
+ *        #GNUNET_NO  Not cancelled, result callback is called.
+ *        #GNUNET_YES Cancelled, result callback is not called.
+ *
+ * @return #GNUNET_YES if the operation was found and removed,
+ *         #GNUNET_NO  if the operation was not found.
+ */
+static int
+op_result (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+           uint64_t op_id, int64_t result_code,
+           const void *data, uint16_t data_size, uint8_t cancel)
+{
+  if (0 == op_id)
+    return GNUNET_NO;
+
+  struct OperationListItem *op = op_find (mgr, op_id);
+  if (NULL == op)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Could not find operation #%" PRIu64 "\n", op_id);
+    return GNUNET_NO;
+  }
+
+  GNUNET_CONTAINER_DLL_remove (mgr->op_head, mgr->op_tail, op);
+
+  if (GNUNET_YES != cancel && NULL != op->result_cb)
+    op->result_cb (op->cls, result_code, data, data_size);
+
+  GNUNET_free (op);
+  return GNUNET_YES;
+}
+
+
+/**
+ * Call the result callback of an operation and remove it.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID.
+ * @param result_code
+ *        Result of the operation.
+ * @param data
+ *        Data result of the operation.
+ * @param data_size
+ *        Size of @a data.
+ *
+ * @return #GNUNET_YES if the operation was found and removed,
+ *         #GNUNET_NO  if the operation was not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_result (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                                 uint64_t op_id, int64_t result_code,
+                                 const void *data, uint16_t data_size)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "%p Received result for operation #%" PRIu64 ": %" PRId64 " (size: 
%u)\n",
+       mgr, op_id, result_code, data_size);
+  return op_result (mgr, op_id, result_code, data, data_size, GNUNET_NO);
+}
+
+
+/**
+ * Cancel an operation.
+ *
+ * @param mgr
+ *        Client manager connection.
+ * @param op_id
+ *        Operation ID.
+ *
+ * @return #GNUNET_YES if the operation was found and removed,
+ *         #GNUNET_NO  if the operation was not found.
+ */
+int
+GNUNET_CLIENT_MANAGER_op_cancel (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
+                                 uint64_t op_id)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "%p Cancelling operation #%" PRIu64  "\n", mgr, op_id);
+  return op_result (mgr, op_id, 0, NULL, 0, GNUNET_YES);
+}




reply via email to

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