GNUnet  0.10.x
gnunet-service-testbed_barriers.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2008--2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "gnunet-service-testbed.h"
29 #include "testbed_api.h"
30 
31 
35 #define MESSAGE_SEND_TIMEOUT(s) \
36  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, s)
37 
38 
42 #define LOCAL_QUORUM_REACHED(barrier) \
43  ((barrier->quorum * GST_num_local_peers) <= (barrier->nreached * 100))
44 
45 
46 #ifdef LOG
47 #undef LOG
48 #endif
49 
53 #define LOG(kind, ...) \
54  GNUNET_log_from(kind, "testbed-barriers", __VA_ARGS__)
55 
56 
60 struct Barrier;
61 
62 
66 struct ClientCtx {
70  struct Barrier *barrier;
71 
75  struct ClientCtx *next;
76 
80  struct ClientCtx *prev;
81 
86 };
87 
88 
92 struct WBarrier {
96  struct WBarrier *next;
97 
101  struct WBarrier *prev;
102 
106  struct Barrier *barrier;
107 
112 
117 
121  uint8_t reached;
122 };
123 
124 
128 struct Barrier {
132  struct GNUNET_HashCode hash;
133 
138 
142  char *name;
143 
147  struct ClientCtx *head;
148 
152  struct ClientCtx *tail;
153 
157  struct WBarrier *whead;
158 
162  struct WBarrier *wtail;
163 
168 
173 
177  unsigned int num_wbarriers;
178 
182  unsigned int num_wbarriers_reached;
183 
187  unsigned int num_wbarriers_inited;
188 
192  unsigned int nreached;
193 
197  unsigned int nslaves;
198 
202  uint8_t quorum;
203 };
204 
205 
210 
214 static struct GNUNET_SERVICE_Handle *ctx;
215 
216 
223 static void
225 {
226  struct ClientCtx *ctx;
227 
230  &barrier->hash,
231  barrier));
232  while (NULL != (ctx = barrier->head))
233  {
235  barrier->tail,
236  ctx);
237  ctx->barrier = NULL;
238  }
239  GNUNET_free(barrier->name);
240  GNUNET_free(barrier);
241 }
242 
243 
249 static void
251 {
252  struct WBarrier *wrapper;
253 
254  while (NULL != (wrapper = barrier->whead))
255  {
258  barrier->wtail,
259  wrapper);
260  GNUNET_free(wrapper);
261  }
262 }
263 
264 
274 static void
276  const char *name,
278  const char *emsg)
279 {
280  struct GNUNET_MQ_Envelope *env;
282  size_t name_len;
283  size_t err_len;
284 
285  GNUNET_assert((NULL == emsg) ||
287  name_len = strlen(name) + 1;
288  err_len = ((NULL == emsg) ? 0 : (strlen(emsg) + 1));
289  env = GNUNET_MQ_msg_extra(msg,
290  name_len + err_len,
292  msg->status = htons(status);
293  msg->name_len = htons((uint16_t)name_len - 1);
294  GNUNET_memcpy(msg->data,
295  name,
296  name_len);
297  GNUNET_memcpy(msg->data + name_len,
298  emsg,
299  err_len);
301  env);
302 }
303 
304 
312 static void
314  const char *emsg)
315 {
316  GNUNET_assert(0 != barrier->status);
317  send_client_status_msg(barrier->mc,
318  barrier->name,
319  barrier->status,
320  emsg);
321 }
322 
323 
330 static int
332  const struct GNUNET_TESTBED_BarrierWait *msg)
333 {
334  return GNUNET_OK; /* always well-formed */
335 }
336 
337 
349 static void
351  const struct GNUNET_TESTBED_BarrierWait *msg)
352 {
353  struct ClientCtx *client_ctx = cls;
354  struct Barrier *barrier;
355  char *name;
356  struct GNUNET_HashCode key;
357  size_t name_len;
358  uint16_t msize;
359 
360  msize = ntohs(msg->header.size);
361  if (NULL == barrier_map)
362  {
363  GNUNET_break(0);
364  GNUNET_SERVICE_client_drop(client_ctx->client);
365  return;
366  }
367  name_len = msize - sizeof(struct GNUNET_TESTBED_BarrierWait);
368  name = GNUNET_malloc(name_len + 1);
369  name[name_len] = '\0';
370  GNUNET_memcpy(name,
371  msg->name,
372  name_len);
373  LOG_DEBUG("Received BARRIER_WAIT for barrier `%s'\n",
374  name);
375  GNUNET_CRYPTO_hash(name,
376  name_len,
377  &key);
378  GNUNET_free(name);
379  if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get(barrier_map, &key)))
380  {
381  GNUNET_break(0);
382  GNUNET_SERVICE_client_drop(client_ctx->client);
383  return;
384  }
385  if (NULL != client_ctx->barrier)
386  {
387  GNUNET_break(0);
388  GNUNET_SERVICE_client_drop(client_ctx->client);
389  return;
390  }
391  client_ctx->barrier = barrier;
393  barrier->tail,
394  client_ctx);
395  barrier->nreached++;
396  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) &&
397  (LOCAL_QUORUM_REACHED(barrier)))
398  {
400  send_barrier_status_msg(barrier,
401  NULL);
402  }
404 }
405 
406 
415 static void *
416 connect_cb(void *cls,
418  struct GNUNET_MQ_Handle *mq)
419 {
420  struct ClientCtx *client_ctx;
421 
422  LOG_DEBUG("Client connected to testbed-barrier service\n");
423  client_ctx = GNUNET_new(struct ClientCtx);
424  client_ctx->client = client;
425  return client_ctx;
426 }
427 
428 
437 static void
438 disconnect_cb(void *cls,
440  void *app_ctx)
441 {
442  struct ClientCtx *client_ctx = app_ctx;
443  struct Barrier *barrier = client_ctx->barrier;
444 
445  if (NULL != barrier)
446  {
448  barrier->tail,
449  client_ctx);
450  client_ctx->barrier = NULL;
451  }
452  GNUNET_free(client_ctx);
453  LOG_DEBUG("Client disconnected from testbed-barrier service\n");
454 }
455 
456 
462 void
464 {
465  struct GNUNET_MQ_MessageHandler message_handlers[] = {
466  GNUNET_MQ_hd_var_size(barrier_wait,
469  NULL),
471  };
472 
473  LOG_DEBUG("Launching testbed-barrier service\n");
474  barrier_map = GNUNET_CONTAINER_multihashmap_create(3,
475  GNUNET_YES);
476  ctx = GNUNET_SERVICE_start("testbed-barrier",
477  cfg,
478  &connect_cb,
479  &disconnect_cb,
480  NULL,
481  message_handlers);
482 }
483 
484 
495 static int
497  const struct GNUNET_HashCode *key,
498  void *value)
499 {
500  struct Barrier *barrier = value;
501 
502  GNUNET_assert(NULL != barrier);
503  cancel_wrappers(barrier);
504  remove_barrier(barrier);
505  return GNUNET_YES;
506 }
507 
508 
512 void
514 {
515  GNUNET_assert(NULL != barrier_map);
519  NULL));
521  GNUNET_assert(NULL != ctx);
522  GNUNET_SERVICE_stop(ctx);
523 }
524 
525 
539 static void
541  const char *name,
542  struct GNUNET_TESTBED_Barrier *b_,
544  const char *emsg)
545 {
546  struct WBarrier *wrapper = cls;
547  struct Barrier *barrier = wrapper->barrier;
548 
549  GNUNET_assert(b_ == wrapper->hbarrier);
550  switch (status)
551  {
554  "Initialising barrier `%s' failed at a sub-controller: %s\n",
555  barrier->name,
556  (NULL != emsg) ? emsg : "NULL");
557  cancel_wrappers(barrier);
558  if (NULL == emsg)
559  emsg = "Initialisation failed at a sub-controller";
561  send_barrier_status_msg(barrier, emsg);
562  return;
563 
566  {
567  GNUNET_break_op(0);
568  return;
569  }
570  barrier->num_wbarriers_reached++;
571  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
572  && (LOCAL_QUORUM_REACHED(barrier)))
573  {
575  send_barrier_status_msg(barrier, NULL);
576  }
577  return;
578 
580  if (0 != barrier->status)
581  {
582  GNUNET_break_op(0);
583  return;
584  }
585  barrier->num_wbarriers_inited++;
586  if (barrier->num_wbarriers_inited == barrier->num_wbarriers)
587  {
589  send_barrier_status_msg(barrier, NULL);
590  }
591  return;
592  }
593 }
594 
595 
602 static void
604 {
605  struct Barrier *barrier = cls;
606 
607  cancel_wrappers(barrier);
609  send_barrier_status_msg(barrier,
610  "Timedout while propagating barrier initialisation\n");
611  remove_barrier(barrier);
612 }
613 
614 
615 
623 int
625  const struct GNUNET_TESTBED_BarrierInit *msg)
626 {
627  return GNUNET_OK; /* always well-formed */
628 }
629 
630 
642 void
644  const struct GNUNET_TESTBED_BarrierInit *msg)
645 {
646  struct GNUNET_SERVICE_Client *client = cls;
647  char *name;
648  struct Barrier *barrier;
649  struct Slave *slave;
650  struct WBarrier *wrapper;
651  struct GNUNET_HashCode hash;
652  size_t name_len;
653  unsigned int cnt;
654  uint16_t msize;
655 
656  if (NULL == GST_context)
657  {
658  GNUNET_break_op(0);
660  return;
661  }
662  if (client != GST_context->client)
663  {
664  GNUNET_break_op(0);
666  return;
667  }
668  msize = ntohs(msg->header.size);
669  name_len = (size_t)msize - sizeof(struct GNUNET_TESTBED_BarrierInit);
670  name = GNUNET_malloc(name_len + 1);
671  GNUNET_memcpy(name, msg->name, name_len);
672  GNUNET_CRYPTO_hash(name, name_len, &hash);
673  LOG_DEBUG("Received BARRIER_INIT for barrier `%s'\n",
674  name);
675  if (GNUNET_YES ==
677  &hash))
678  {
679  send_client_status_msg(client,
680  name,
682  "A barrier with the same name already exists");
683  GNUNET_free(name);
685  return;
686  }
687  barrier = GNUNET_new(struct Barrier);
688  barrier->hash = hash;
689  barrier->quorum = msg->quorum;
690  barrier->name = name;
691  barrier->mc = client;
694  &barrier->hash,
695  barrier,
698  /* Propagate barrier init to subcontrollers */
699  for (cnt = 0; cnt < GST_slave_list_size; cnt++)
700  {
701  if (NULL == (slave = GST_slave_list[cnt]))
702  continue;
703  if (NULL == slave->controller)
704  {
705  GNUNET_break(0);/* May happen when we are connecting to the controller */
706  continue;
707  }
708  wrapper = GNUNET_new(struct WBarrier);
709  wrapper->barrier = barrier;
710  wrapper->controller = slave->controller;
712  barrier->wtail,
713  wrapper);
714  barrier->num_wbarriers++;
716  barrier->name,
717  barrier->quorum,
719  wrapper,
720  GNUNET_NO);
721  }
722  if (NULL == barrier->whead) /* No further propagation */
723  {
725  LOG_DEBUG("Sending GNUNET_TESTBED_BARRIERSTATUS_INITIALISED for barrier `%s'\n",
726  barrier->name);
727  send_barrier_status_msg(barrier, NULL);
728  }
729  else
732  barrier);
733 }
734 
735 
743 int
745  const struct GNUNET_TESTBED_BarrierCancel *msg)
746 {
747  return GNUNET_OK; /* all are well-formed */
748 }
749 
750 
762 void
764  const struct GNUNET_TESTBED_BarrierCancel *msg)
765 {
766  struct GNUNET_SERVICE_Client *client = cls;
767  char *name;
768  struct Barrier *barrier;
769  struct GNUNET_HashCode hash;
770  size_t name_len;
771  uint16_t msize;
772 
773  if (NULL == GST_context)
774  {
775  GNUNET_break_op(0);
777  return;
778  }
779  if (client != GST_context->client)
780  {
781  GNUNET_break_op(0);
783  return;
784  }
785  msize = ntohs(msg->header.size);
786  name_len = msize - sizeof(struct GNUNET_TESTBED_BarrierCancel);
787  name = GNUNET_malloc(name_len + 1);
788  GNUNET_memcpy(name,
789  msg->name,
790  name_len);
791  LOG_DEBUG("Received BARRIER_CANCEL for barrier `%s'\n",
792  name);
793  GNUNET_CRYPTO_hash(name,
794  name_len,
795  &hash);
796  if (GNUNET_NO ==
798  &hash))
799  {
800  GNUNET_break_op(0);
802  return;
803  }
804  barrier = GNUNET_CONTAINER_multihashmap_get(barrier_map,
805  &hash);
806  GNUNET_assert(NULL != barrier);
807  cancel_wrappers(barrier);
808  remove_barrier(barrier);
810 }
811 
812 
820 int
822  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
823 {
824  uint16_t msize;
825  uint16_t name_len;
826  const char *name;
828 
829  msize = ntohs(msg->header.size) - sizeof(*msg);
830  status = ntohs(msg->status);
832  {
833  GNUNET_break_op(0); /* current we only expect BARRIER_CROSSED
834  status message this way */
835  return GNUNET_SYSERR;
836  }
837  name = msg->data;
838  name_len = ntohs(msg->name_len);
839  if ((name_len + 1) != msize)
840  {
841  GNUNET_break_op(0);
842  return GNUNET_SYSERR;
843  }
844  if ('\0' != name[name_len])
845  {
846  GNUNET_break_op(0);
847  return GNUNET_SYSERR;
848  }
849  return GNUNET_OK;
850 }
851 
852 
861 void
863  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
864 {
865  struct GNUNET_SERVICE_Client *client = cls;
866  struct Barrier *barrier;
867  struct ClientCtx *client_ctx;
868  struct WBarrier *wrapper;
869  const char *name;
870  struct GNUNET_HashCode key;
871  uint16_t name_len;
872  struct GNUNET_MQ_Envelope *env;
873 
874  if (NULL == GST_context)
875  {
876  GNUNET_break_op(0);
878  return;
879  }
880  if (client != GST_context->client)
881  {
882  GNUNET_break_op(0);
884  return;
885  }
886  name = msg->data;
887  name_len = ntohs(msg->name_len);
888  LOG_DEBUG("Received BARRIER_STATUS for barrier `%s'\n",
889  name);
890  GNUNET_CRYPTO_hash(name,
891  name_len,
892  &key);
893  barrier = GNUNET_CONTAINER_multihashmap_get(barrier_map,
894  &key);
895  if (NULL == barrier)
896  {
897  GNUNET_break_op(0);
899  return;
900  }
902  for (client_ctx = barrier->head; NULL != client_ctx; client_ctx = client_ctx->next) /* Notify peers */
903  {
904  env = GNUNET_MQ_msg_copy(&msg->header);
906  env);
907  }
912  for (wrapper = barrier->whead; NULL != wrapper; wrapper = wrapper->next)
913  {
915  GNUNET_copy_message(&msg->header));
916  }
917 }
918 
919 /* end of gnunet-service-testbed_barriers.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS
Message for signalling status of a barrier.
Interface for the barrier initialisation handler routine.
struct WBarrier * wtail
DLL tail for the list of barrier handles.
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:651
unsigned int num_wbarriers_reached
Number of wrapped barriers reached so far.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GST_barriers_destroy()
Function to stop the barrier service.
struct WBarrier * next
DLL next pointer.
Context to be associated with each client.
Handle to interact with a GNUnet testbed controller.
Definition: testbed_api.h:191
char name[0]
The name of the barrier they have reached.
Definition: testbed.h:831
Message to cancel a barrier.
Definition: testbed.h:778
Handle to a service.
Definition: service.c:114
static struct GNUNET_CONTAINER_MultiHashMap * barrier_map
Hashtable handle for storing initialised barriers.
data structures shared amongst components of TESTBED service
uint16_t name_len
strlen of the barrier name
Definition: testbed.h:808
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2424
int check_barrier_init(void *cls, const struct GNUNET_TESTBED_BarrierInit *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
static int check_barrier_wait(void *cls, const struct GNUNET_TESTBED_BarrierWait *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT
Message sent by a peer when it has reached a barrier and is waiting for it to be crossed.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_SERVICE_Handle * GNUNET_SERVICE_start(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SERVICE_ConnectHandler connect_cb, GNUNET_SERVICE_DisconnectHandler disconnect_cb, void *cls, const struct GNUNET_MQ_MessageHandler *handlers)
Low-level function to start a service if the scheduler is already running.
Definition: service.c:1874
void handle_barrier_status(void *cls, const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Structure representing a connected(directly-linked) controller.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS.
Definition: testbed.h:798
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
static void send_barrier_status_msg(struct Barrier *barrier, const char *emsg)
Sends a barrier failed message.
struct GNUNET_TESTBED_Barrier * hbarrier
The barrier handle from API.
enum GNUNET_TESTBED_BarrierStatus status
The status of this barrier.
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL.
Definition: testbed.h:782
Message sent from peers to the testbed-barrier service to indicate that they have reached a barrier a...
Definition: testbed.h:822
GNUNET_TESTBED_BarrierStatus
Status of a barrier.
unsigned int num_wbarriers
Number of barriers wrapped in the above DLL.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t status
status.
Definition: testbed.h:803
Handle to a client that is connected to a service.
Definition: service.c:246
struct ClientCtx * next
DLL next ptr.
#define MESSAGE_SEND_TIMEOUT(s)
timeout for outgoing message transmissions in seconds
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
int check_barrier_cancel(void *cls, const struct GNUNET_TESTBED_BarrierCancel *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
void * cls
Closure for mv and cb.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
static char * value
Value of the record to add/remove.
void handle_barrier_init(void *cls, const struct GNUNET_TESTBED_BarrierInit *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct ClientCtx * prev
DLL prev ptr.
struct WBarrier * whead
DLL head for the list of barrier handles.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
unsigned int nreached
Number of peers which have reached this barrier.
void GST_barriers_init(struct GNUNET_CONFIGURATION_Handle *cfg)
Function to initialise barrriers component.
static void cancel_wrappers(struct Barrier *barrier)
Cancels all subcontroller barrier handles.
static struct GNUNET_SERVICE_Handle * ctx
Service context.
struct GNUNET_SERVICE_Client * client
The client handle associated with this context.
uint16_t status
See PRISM_STATUS_*-constants.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_TESTBED_Controller * controller
Handle to the slave controller where this wrapper creates a barrier.
char name[0]
The barrier name.
Definition: testbed.h:787
void GNUNET_TESTBED_barrier_cancel(struct GNUNET_TESTBED_Barrier *barrier)
Cancel a barrier.
Definition: testbed_api.c:2451
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1907
static void handle_barrier_wait(void *cls, const struct GNUNET_TESTBED_BarrierWait *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
Handle for barrier.
Definition: testbed_api.h:274
A 512-bit hashcode.
static void disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Functions with this signature are called whenever a client is disconnected on the network level...
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2315
struct GNUNET_HashCode hash
The hashcode of the barrier name.
Message handler for a specific message type.
struct GNUNET_TESTBED_Barrier * GNUNET_TESTBED_barrier_init_(struct GNUNET_TESTBED_Controller *controller, const char *name, unsigned int quorum, GNUNET_TESTBED_barrier_status_cb cb, void *cls, int echo)
Initialise a barrier and call the given callback when the required percentage of peers (quorum) reach...
Definition: testbed_api.c:2363
struct GNUNET_SERVICE_Client * mc
The client handle to the master controller.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
uint8_t reached
Has this barrier been crossed?
unsigned int nslaves
Number of slaves we have initialised this barrier.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
char data[0]
the barrier name (0-terminated) concatenated with an error message (0-terminated) if the status were ...
Definition: testbed.h:814
int check_barrier_status(void *cls, const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
void GNUNET_TESTBED_queue_message_(struct GNUNET_TESTBED_Controller *controller, struct GNUNET_MessageHeader *msg)
Queues a message in send queue for sending to the service.
Definition: testbed_api.c:1328
unsigned int num_wbarriers_inited
Number of wrapped barrier initialised so far.
const char * name
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT.
Definition: testbed.h:761
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void wbarrier_status_cb(void *cls, const char *name, struct GNUNET_TESTBED_Barrier *b_, enum GNUNET_TESTBED_BarrierStatus status, const char *emsg)
Functions of this type are to be given as callback argument to GNUNET_TESTBED_barrier_init().
#define LOG(kind,...)
Logging shorthand.
#define LOCAL_QUORUM_REACHED(barrier)
Test to see if local peers have reached the required quorum of a barrier.
static void * connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Function called when a client connects to the testbed-barrier service.
Interface for functions internally exported from testbed_api.c.
Handle to a message queue.
Definition: mq.c:84
char * name
The name of the barrier.
uint8_t quorum
Quorum percentage to be reached.
struct GNUNET_SERVICE_Client * client
The client handle.
configuration data
Definition: configuration.c:83
struct Context * GST_context
The master context; generated with the first INIT message.
struct WBarrier * prev
DLL prev pointer.
struct ClientCtx * head
DLL head for the list of clients waiting for this barrier.
struct GNUNET_SCHEDULER_Task * tout_task
Identifier for the timeout task.
struct ClientCtx * tail
DLL tail for the list of clients waiting for this barrier.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Wrapper around Barrier handle.
Entry in list of pending tasks.
Definition: scheduler.c:131
uint8_t quorum
The quorum percentage needed for crossing the barrier.
Definition: testbed.h:766
static void fwd_tout_barrier_init(void *cls)
Function called upon timeout while waiting for a response from the subcontrollers to barrier init mes...
struct GNUNET_TESTBED_Controller * controller
The controller handle.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
Barrier initialised successfully.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT.
Definition: testbed.h:826
static int barrier_destroy_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries.
#define GNUNET_YES
Definition: gnunet_common.h:77
Message for signalling status changes of a barrier.
Definition: testbed.h:794
struct Barrier * barrier
The barrier this client is waiting for.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
char name[0]
name of the barrier.
Definition: testbed.h:771
Message to initialise a barrier.
Definition: testbed.h:757
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct Barrier * barrier
The local barrier associated with the creation of this wrapper.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2234
#define LOG_DEBUG(...)
Debug logging shorthand.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void remove_barrier(struct Barrier *barrier)
Function to remove a barrier from the barrier map and cleanup resources occupied by a barrier...
void handle_barrier_cancel(void *cls, const struct GNUNET_TESTBED_BarrierCancel *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
static void send_client_status_msg(struct GNUNET_SERVICE_Client *client, const char *name, enum GNUNET_TESTBED_BarrierStatus status, const char *emsg)
Send a status message about a barrier to the given client.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.