[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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r28964 - in gnunet/src: include testbed,
gnunet <=