+/**
+ * Functions of this type are to be given as callback argument to
+ * GNUNET_TESTBED_barrier_init(). The callback will be called when status
+ * information is available for the barrier.
+ *
+ * @param cls the closure given to GNUNET_TESTBED_barrier_init()
+ * @param name the name of the barrier
+ * @param b_ the barrier handle
+ * @param status status of the barrier; GNUNET_OK if the barrier is crossed;
+ * GNUNET_SYSERR upon error
+ * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the
+ * error messsage
+ */
+static void
+wbarrier_status_cb (void *cls, const char *name,
+ struct GNUNET_TESTBED_Barrier *b_,
+ enum GNUNET_TESTBED_BarrierStatus status,
+ const char *emsg)
+{
+ struct WBarrier *wrapper = cls;
+ struct Barrier *barrier = wrapper->barrier;
+
+ GNUNET_assert (b_ == wrapper->hbarrier);
+ wrapper->hbarrier = NULL;
+ GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
+ GNUNET_free (wrapper);
+ switch (status)
+ {
+ case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Initialising barrier `%s' failed at a sub-controller: %s\n",
+ barrier->name, (NULL != emsg) ? emsg : "NULL");
+ cancel_wrappers (barrier);
+ if (NULL == emsg)
+ emsg = "Initialisation failed at a sub-controller";
+ barrier->status = GNUNET_TESTBED_BARRIERSTATUS_ERROR;
+ send_barrier_status_msg (barrier, emsg);
+ return;
+ case GNUNET_TESTBED_BARRIERSTATUS_CROSSED:
+ if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED != barrier->status)
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ barrier->num_wbarriers_reached++;
+ if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
+ && (LOCAL_QUORUM_REACHED (barrier)))
+ {
+ barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED;
+ send_barrier_status_msg (barrier, NULL);
+ }
+ return;
+ case GNUNET_TESTBED_BARRIERSTATUS_INITIALISED:
+ if (0 != barrier->status)
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ barrier->num_wbarriers_inited++;
+ if (barrier->num_wbarriers_inited == barrier->num_wbarriers)
+ {
+ barrier->status = GNUNET_TESTBED_BARRIERSTATUS_INITIALISED;
+ send_barrier_status_msg (barrier, NULL);
+ }
+ return;
+ }
+}
+
+
+/**
+ * Function called upon timeout while waiting for a response from the
+ * subcontrollers to barrier init message
+ *
+ * @param cls barrier
+ * @param tc scheduler task context
+ */
+static void
+fwd_tout_barrier_init (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct Barrier *barrier = cls;
+
+ cancel_wrappers (barrier);
+ barrier->status = GNUNET_TESTBED_BARRIERSTATUS_ERROR;
+ send_barrier_status_msg (barrier,
+ "Timedout while propagating barrier initialisation\n");
+ remove_barrier (barrier);
+}
+
+