gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r33169 - in gnunet/src: include peerstore


From: gnunet
Subject: [GNUnet-SVN] r33169 - in gnunet/src: include peerstore
Date: Mon, 5 May 2014 19:49:53 +0200

Author: otarabai
Date: 2014-05-05 19:49:52 +0200 (Mon, 05 May 2014)
New Revision: 33169

Modified:
   gnunet/src/include/gnunet_peerstore_service.h
   gnunet/src/peerstore/peerstore_api.c
Log:
towards PEERSTORE api


Modified: gnunet/src/include/gnunet_peerstore_service.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_service.h       2014-05-05 15:49:21 UTC 
(rev 33168)
+++ gnunet/src/include/gnunet_peerstore_service.h       2014-05-05 17:49:52 UTC 
(rev 33169)
@@ -37,7 +37,33 @@
 #endif
 #endif
 
+/**
+ * Handle to the peerstore service.
+ */
+struct GNUNET_PEERSTORE_Handle;
 
+/**
+ * Context for add requests
+ */
+struct GNUNET_PEERSTORE_AddContext;
+
+/**
+ * Continuation called with a status result.
+ *
+ * @param cls closure
+ * @param emsg error message, NULL on success
+ */
+typedef void (*GNUNET_PEERSTORE_Continuation)(void *cls,
+               const char *emsg);
+
+/**
+ * Continuation called after an Add is completed
+ *
+ * @param cls closure
+ * @param success #GNUNET_YES / #GNUNET_NO
+ */
+typedef void (*GNUNET_PEERSTORE_AddContinuation)(void *cls, int success);
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: gnunet/src/peerstore/peerstore_api.c
===================================================================
--- gnunet/src/peerstore/peerstore_api.c        2014-05-05 15:49:21 UTC (rev 
33168)
+++ gnunet/src/peerstore/peerstore_api.c        2014-05-05 17:49:52 UTC (rev 
33169)
@@ -33,15 +33,279 @@
 /************************      DATA STRUCTURES     
****************************/
 
/******************************************************************************/
 
+/**
+ * Handle to the peerstore service.
+ */
+struct GNUNET_PEERSTORE_Handle
+{
 
+  /**
+   * Our configuration.
+   */
+    const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Connection to the service.
+   */
+  struct GNUNET_CLIENT_Connection *client;
+
+  /**
+   * Head of transmission queue.
+   */
+  struct GNUNET_PEERSTORE_AddContext *rc_head;
+
+  /**
+   * Tail of transmission queue.
+   */
+  struct GNUNET_PEERSTORE_AddContext *rc_tail;
+
+  /**
+   * Handle for the current transmission request, or NULL if none is pending.
+   */
+  struct GNUNET_CLIENT_TransmitHandle *th;
+
+  /**
+   * ID for a reconnect task.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier r_task;
+
+  /**
+   * Are we now receiving?
+   */
+  int in_receive;
+
+};
+
+/**
+ * Entry in the transmission queue to PEERSTORE service.
+ *
+ */
+struct GNUNET_PEERSTORE_AddContext
+{
+  /**
+   * This is a linked list.
+   */
+  struct GNUNET_PEERSTORE_AddContext *next;
+
+  /**
+   * This is a linked list.
+   */
+  struct GNUNET_PEERSTORE_AddContext *prev;
+
+  /**
+   * Handle to the PEERSTORE service.
+   */
+  struct GNUNET_PEERSTORE_Handle *h;
+
+  /**
+   * Function to call after request has been transmitted, or NULL.
+   */
+  GNUNET_PEERSTORE_Continuation cont;
+
+  /**
+   * Closure for 'cont'.
+   */
+  void *cont_cls;
+
+  /**
+   * Number of bytes of the request message (follows after this struct).
+   */
+  size_t size;
+
+};
+
 
/******************************************************************************/
 /***********************         DECLARATIONS         
*************************/
 
/******************************************************************************/
 
+/**
+ * Close the existing connection to PEERSTORE and reconnect.
+ *
+ * @param h handle to the service
+ */
+static void
+reconnect (struct GNUNET_PEERSTORE_Handle *h);
 
+/**
+ * Check if we have a request pending in the transmission queue and are
+ * able to transmit it right now.  If so, schedule transmission.
+ *
+ * @param h handle to the service
+ */
+static void
+trigger_transmit (struct GNUNET_PEERSTORE_Handle *h);
+
 
/******************************************************************************/
 /*******************         CONNECTION FUNCTIONS         
*********************/
 
/******************************************************************************/
 
+/**
+ * Connect to the PEERSTORE service.
+ *
+ * @return NULL on error
+ */
+struct GNUNET_PEERSTORE_Handle *
+GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_PEERSTORE_Handle *h;
 
+  client = GNUNET_CLIENT_connect ("peerstore", cfg);
+  if(NULL == client)
+    return NULL;
+  h = GNUNET_new (struct GNUNET_PEERSTORE_Handle);
+  h->client = client;
+  h->cfg = cfg;
+  return h;
+}
+
+/**
+ * Disconnect from the PEERSTORE service
+ *
+ * @param h handle to disconnect
+ */
+void
+GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
+{
+  if (NULL != h->client)
+  {
+    GNUNET_CLIENT_disconnect (h->client);
+    h->client = NULL;
+  }
+  GNUNET_free (h);
+}
+
+/**
+ * Task scheduled to re-try connecting to the PEERSTORE service.
+ *
+ * @param cls the 'struct GNUNET_PEERSTORE_Handle'
+ * @param tc scheduler context
+ */
+static void
+reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_PEERSTORE_Handle *h = cls;
+
+  h->r_task = GNUNET_SCHEDULER_NO_TASK;
+  reconnect (h);
+}
+
+/**
+ * Close the existing connection to PEERSTORE and reconnect.
+ *
+ * @param h handle to the service
+ */
+static void
+reconnect (struct GNUNET_PEERSTORE_Handle *h)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
+  {
+    GNUNET_SCHEDULER_cancel (h->r_task);
+    h->r_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  if (NULL != h->th)
+  {
+    GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
+    h->th = NULL;
+  }
+  if (NULL != h->client)
+  {
+    GNUNET_CLIENT_disconnect (h->client);
+    h->client = NULL;
+  }
+  h->in_receive = GNUNET_NO;
+  h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg);
+  if (NULL == h->client)
+  {
+    h->r_task =
+        GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 
&reconnect_task,
+                                      h);
+    return;
+  }
+  trigger_transmit (h);
+}
+
+/**
+ * Transmit the request at the head of the transmission queue
+ * and trigger continuation (if any).
+ *
+ * @param cls the 'struct GNUNET_PEERSTORE_Handle' (with the queue)
+ * @param size size of the buffer (0 on error)
+ * @param buf where to copy the message
+ * @return number of bytes copied to buf
+ */
+static size_t
+do_transmit (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_PEERSTORE_Handle *h = cls;
+  struct GNUNET_PEERSTORE_AddContext *rc = h->rc_head;
+  size_t ret;
+
+  h->th = NULL;
+  if (NULL == rc)
+    return 0; /* request was cancelled in the meantime */
+  if (NULL == buf)
+  {
+    /* PEERSTORE service died */
+    LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+         "Failed to transmit message to `%s' service.\n", "PEERSTORE");
+    GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
+    reconnect (h);
+    if (NULL != rc->cont)
+      rc->cont (rc->cont_cls, _("failed to transmit request (service down?)"));
+    GNUNET_free (rc);
+    return 0;
+  }
+  ret = rc->size;
+  if (size < ret)
+  {
+    /* change in head of queue (i.e. cancel + add), try again */
+    trigger_transmit (h);
+    return 0;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Transmitting request of size %u to `%s' service.\n", ret, "PEERSTORE");
+  memcpy (buf, &rc[1], ret);
+  GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
+  trigger_transmit (h);
+  if (NULL != rc->cont)
+    rc->cont (rc->cont_cls, NULL);
+  GNUNET_free (rc);
+  return ret;
+}
+
+/**
+ * Check if we have a request pending in the transmission queue and are
+ * able to transmit it right now.  If so, schedule transmission.
+ *
+ * @param h handle to the service
+ */
+static void
+trigger_transmit (struct GNUNET_PEERSTORE_Handle *h)
+{
+  struct GNUNET_PEERSTORE_AddContext *rc;
+
+  if (NULL == (rc = h->rc_head))
+    return; /* no requests queued */
+  if (NULL != h->th)
+    return; /* request already pending */
+  if (NULL == h->client)
+  {
+    /* disconnected, try to reconnect */
+    reconnect (h);
+    return;
+  }
+  h->th =
+    GNUNET_CLIENT_notify_transmit_ready (h->client, rc->size,
+           GNUNET_TIME_UNIT_FOREVER_REL,
+           GNUNET_YES,
+           &do_transmit, h);
+}
+
+/******************************************************************************/
+/*******************           STORE FUNCTIONS            
*********************/
+/******************************************************************************/
+
+
+
 /* end of peerstore_api.c */




reply via email to

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