gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28964 - in gnunet/src: include testbed


From: gnunet
Subject: [GNUnet-SVN] r28964 - in gnunet/src: include testbed
Date: Tue, 3 Sep 2013 11:12:58 +0200

Author: harsha
Date: 2013-09-03 11:12:57 +0200 (Tue, 03 Sep 2013)
New Revision: 28964

Modified:
   gnunet/src/include/gnunet_testbed_service.h
   gnunet/src/testbed/gnunet-helper-testbed.c
   gnunet/src/testbed/gnunet-service-testbed_barriers.c
   gnunet/src/testbed/testbed.h
   gnunet/src/testbed/testbed_api_barriers.c
Log:
- barrier wait API


Modified: gnunet/src/include/gnunet_testbed_service.h
===================================================================
--- gnunet/src/include/gnunet_testbed_service.h 2013-09-03 07:42:26 UTC (rev 
28963)
+++ gnunet/src/include/gnunet_testbed_service.h 2013-09-03 09:12:57 UTC (rev 
28964)
@@ -1551,6 +1551,53 @@
 GNUNET_TESTBED_barrier_cancel (struct GNUNET_TESTBED_Barrier *barrier);
 
 
+/**
+ * Opaque handle for barrier wait
+ */
+struct GNUNET_TESTBED_BarrierWaitHandle;
+
+
+/**
+ * Functions of this type are to be given as acallback argumetn to
+ * GNUNET_TESTBED_barrier_wait().  The callback will be called when the barrier
+ * corresponding given in GNUNET_TESTBED_barrier_wait() is crossed or 
cancelled.
+ *
+ * @param cls closure pointer given to GNUNET_TESTBED_barrier_wait()
+ * @param name the barrier name
+ * @param status GNUNET_SYSERR in case of error while waiting for the barrier;
+ *   GNUNET_OK if the barrier is crossed
+ */
+typedef void (*GNUNET_TESTBED_barrier_wait_cb) (void *cls,
+                                                const char *name,
+                                                int estatus);
+
+
+/**
+ * Wait for a barrier to be crossed.  This function should be called by the
+ * peers which have been started by the testbed.  If the peer is not started by
+ * testbed this function may return error
+ *
+ * @param name the name of the barrier
+ * @param cb the barrier wait callback
+ * @param cls the closure for the above callback
+ * @return barrier wait handle which can be used to cancel the waiting at
+ *   anytime before the callback is called.  NULL upon error.
+ */
+struct GNUNET_TESTBED_BarrierWaitHandle *
+GNUNET_TESTBED_barrier_wait (const char *name,
+                             GNUNET_TESTBED_barrier_wait_cb cb,
+                             void *cls);
+
+
+/**
+ * Cancel a barrier wait handle
+ *
+ * @param h the barrier wait handle
+ */
+void
+GNUNET_TESTBED_barrier_wait_cancel (struct GNUNET_TESTBED_BarrierWaitHandle 
*h);
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: gnunet/src/testbed/gnunet-helper-testbed.c
===================================================================
--- gnunet/src/testbed/gnunet-helper-testbed.c  2013-09-03 07:42:26 UTC (rev 
28963)
+++ gnunet/src/testbed/gnunet-helper-testbed.c  2013-09-03 09:12:57 UTC (rev 
28964)
@@ -421,6 +421,8 @@
   }
   LOG_DEBUG ("Staring testbed with config: %s\n", config);
   binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-testbed");
+  /* expose testbed configuration through env variable */
+  GNUNET_assert (0 == setenv (ENV_TESTBED_CONFIG, config, 1));
   testbed =
       GNUNET_OS_start_process (PIPE_CONTROL,
                                GNUNET_OS_INHERIT_STD_ERR /*verbose? */ , NULL,

Modified: gnunet/src/testbed/gnunet-service-testbed_barriers.c
===================================================================
--- gnunet/src/testbed/gnunet-service-testbed_barriers.c        2013-09-03 
07:42:26 UTC (rev 28963)
+++ gnunet/src/testbed/gnunet-service-testbed_barriers.c        2013-09-03 
09:12:57 UTC (rev 28964)
@@ -224,10 +224,6 @@
    */
   uint8_t quorum;
   
-  /**
-   * Was there a timeout while propagating initialisation
-   */
-  uint8_t timedout;
 };
 
 
@@ -610,8 +606,9 @@
   wrapper->hbarrier = NULL;
   GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
   GNUNET_free (wrapper);
-  if (BARRIER_STATUS_ERROR == status)
+  switch (status)
   {
+  case BARRIER_STATUS_ERROR:
     LOG (GNUNET_ERROR_TYPE_ERROR,
          "Initialising barrier `%s' failed at a sub-controller: %s\n",
          barrier->name, (NULL != emsg) ? emsg : "NULL");
@@ -621,9 +618,6 @@
     barrier->status = BARRIER_STATUS_ERROR;
     send_barrier_status_msg (barrier, emsg);
     return;
-  }
-  switch (status)
-  {
   case BARRIER_STATUS_CROSSED:
     if (BARRIER_STATUS_INITIALISED != barrier->status)
     {
@@ -637,7 +631,7 @@
       barrier->status = BARRIER_STATUS_CROSSED;
       send_barrier_status_msg (barrier, NULL);
     }
-    break;
+    return;
   case BARRIER_STATUS_INITIALISED:
     if (0 != barrier->status)
     {
@@ -650,11 +644,8 @@
       barrier->status = BARRIER_STATUS_INITIALISED;
       send_barrier_status_msg (barrier, NULL);
     }
-    break;
-  case BARRIER_STATUS_ERROR:
-    GNUNET_assert (0);
+    return;
   }
-  return;
 }
 
 
@@ -670,8 +661,6 @@
 {
   struct Barrier *barrier = cls;
   
-  barrier->nslaves--;
-  barrier->timedout = GNUNET_YES;
   cancel_wrappers (barrier);
   barrier->status = BARRIER_STATUS_ERROR;
   send_barrier_status_msg (barrier,

Modified: gnunet/src/testbed/testbed.h
===================================================================
--- gnunet/src/testbed/testbed.h        2013-09-03 07:42:26 UTC (rev 28963)
+++ gnunet/src/testbed/testbed.h        2013-09-03 09:12:57 UTC (rev 28964)
@@ -774,6 +774,13 @@
 
 
 /**
+ * The environmental variable which when available refers to the configuration
+ * file the local testbed controller is using
+ */
+#define ENV_TESTBED_CONFIG "GNUNET_TESTBED_CONTROLLER_CONFIG"
+
+
+/**
  * Message to initialise a barrier
  */
 struct GNUNET_TESTBED_BarrierInit

Modified: gnunet/src/testbed/testbed_api_barriers.c
===================================================================
--- gnunet/src/testbed/testbed_api_barriers.c   2013-09-03 07:42:26 UTC (rev 
28963)
+++ gnunet/src/testbed/testbed_api_barriers.c   2013-09-03 09:12:57 UTC (rev 
28964)
@@ -241,4 +241,219 @@
   barrier_remove (barrier);
 }
 
+
+/**
+ * Barrier wait handle
+ */
+struct GNUNET_TESTBED_BarrierWaitHandle
+{
+  /**
+   * The name of the barrier
+   */
+  char *name;
+  
+  /**
+   * Then configuration used for the client connection
+   */
+  struct GNUNET_CONFIGURATION_Handle *cfg;  
+
+  /**
+   * The client connection
+   */
+  struct GNUNET_CLIENT_Connection *conn;
+
+  /**
+   * Transmit handle
+   */
+  struct GNUNET_CLIENT_TransmitHandle *tx;
+
+  /**
+   * The message to transmit with tx
+   */
+  struct GNUNET_MessageHeader *msg;
+
+  /**
+   * The barrier wait callback
+   */
+  GNUNET_TESTBED_barrier_wait_cb cb;
+
+  /**
+   * The closure for the above callback
+   */
+  void *cls;
+};
+
+
+/**
+ * Function to destroy barrier wait handle
+ *
+ * @param h the handle to destroy
+ */
+static void
+destroy_handle (struct GNUNET_TESTBED_BarrierWaitHandle *h)
+{
+  GNUNET_free (h->name);
+  if (NULL != h->tx)
+    GNUNET_CLIENT_notify_transmit_ready_cancel (h->tx);
+  if (NULL != h->conn)
+    GNUNET_CLIENT_disconnect (h->conn);
+  if (NULL != h->msg)
+    GNUNET_free (h->msg);
+  GNUNET_CONFIGURATION_destroy (h->cfg);
+  GNUNET_free (h);
+}
+
+
+/**
+ * Type of a function to call when we receive a message
+ * from the service.
+ *
+ * @param cls closure
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void
+receive_handler (void *cls, const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_TESTBED_BarrierWaitHandle *h = cls;
+  const struct GNUNET_TESTBED_BarrierStatusMsg *msg;
+  uint16_t msize;
+  
+  if (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS != ntohs (message->type))
+  {
+    GNUNET_break_op (0);
+    goto fail;
+  } 
+  msize = ntohs (message->size);
+  if (msize <= sizeof (struct GNUNET_TESTBED_BarrierStatusMsg))
+  {
+    GNUNET_break_op (0);
+    goto fail;
+  } 
+  msg = (const struct GNUNET_TESTBED_BarrierStatusMsg *) message;
+  switch (ntohs (msg->status))
+  {
+  case BARRIER_STATUS_ERROR:
+    goto fail;
+  case BARRIER_STATUS_INITIALISED:
+    GNUNET_break (0);           /* FIXME */
+    goto destroy;
+  case BARRIER_STATUS_CROSSED:
+    h->cb (h->cls, h->name, GNUNET_OK);
+    goto destroy;
+  }
+
+ fail:
+  h->cb (h->cls, h->name, GNUNET_SYSERR);
+
+ destroy:
+  destroy_handle (h);
+}
+
+
+/**
+ * Function called to notify a client about the connection
+ * begin ready to queue more data.  "buf" will be
+ * NULL and "size" zero if the connection was closed for
+ * writing in the meantime.
+ *
+ * @param cls closure
+ * @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_TESTBED_BarrierWaitHandle *h = cls;
+  uint16_t msize;
+  
+  h->tx = NULL;
+  if ((0 == size) || (NULL == buf))
+  {
+    destroy_handle (h);
+    return 0;
+  }
+  msize = htons (h->msg->size);
+  GNUNET_assert (msize <= size);
+  (void) memcpy (buf, h->msg, msize);
+  GNUNET_free (h->msg);
+  h->msg = NULL;
+  GNUNET_CLIENT_receive (h->conn, &receive_handler, h, 
GNUNET_TIME_UNIT_FOREVER_REL);
+  return msize;
+}
+
+
+/**
+ * Wait for a barrier to be crossed.  This function should be called by the
+ * peers which have been started by the testbed.  If the peer is not started by
+ * testbed this function may return error
+ *
+ * @param name the name of the barrier
+ * @param cb the barrier wait callback
+ * @param cls the closure for the above callback
+ * @return barrier wait handle which can be used to cancel the waiting at
+ *   anytime before the callback is called.  NULL upon error.
+ */
+struct GNUNET_TESTBED_BarrierWaitHandle *
+GNUNET_TESTBED_barrier_wait (const char *name,
+                             GNUNET_TESTBED_barrier_wait_cb cb,
+                             void *cls)
+{
+  struct GNUNET_TESTBED_BarrierWait *msg;
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_TESTBED_BarrierWaitHandle *h;
+  char *cfg_filename;
+  size_t name_len;
+  uint16_t msize;
+
+  GNUNET_assert (NULL != cb);
+  GNUNET_assert (NULL != name);
+  cfg_filename = getenv (ENV_TESTBED_CONFIG);
+  if (NULL == cfg_filename)
+    return NULL;
+  cfg = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfg_filename));
+  {
+    GNUNET_CONFIGURATION_destroy (cfg);
+    return NULL;
+  }
+  h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_BarrierWaitHandle));
+  h->name = GNUNET_strdup (name);
+  h->cfg = cfg;
+  h->conn = GNUNET_CLIENT_connect ("testbed-barrier", h->cfg);
+  h->cb = cb;
+  h->cls = cls;
+  if (NULL == h->conn)
+  {
+    destroy_handle (h);
+    return NULL;
+  }
+  name_len = strlen (name);
+  msize = sizeof (struct GNUNET_TESTBED_BarrierWait) + name_len;
+  msg = GNUNET_malloc (msize);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT);
+  msg->header.size = htons (msize);
+  (void) memcpy (msg->name, name, name_len);
+  h->msg = &msg->header;
+  h->tx = 
+      GNUNET_CLIENT_notify_transmit_ready (h->conn, msize,
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           GNUNET_NO,
+                                           &transmit_notify,
+                                           h);
+  return h;
+}
+
+
+/**
+ * Cancel a barrier wait handle
+ *
+ * @param h the barrier wait handle
+ */
+void
+GNUNET_TESTBED_barrier_wait_cancel (struct GNUNET_TESTBED_BarrierWaitHandle *h)
+{
+  destroy_handle (h);
+}
+
 /* end of testbed_api_barriers.c */




reply via email to

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