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
67 {
71  struct Barrier *barrier;
72 
76  struct ClientCtx *next;
77 
81  struct ClientCtx *prev;
82 
87 
88 };
89 
90 
94 struct WBarrier
95 {
99  struct WBarrier *next;
100 
104  struct WBarrier *prev;
105 
109  struct Barrier *barrier;
110 
115 
120 
124  uint8_t reached;
125 };
126 
127 
131 struct Barrier
132 {
136  struct GNUNET_HashCode hash;
137 
142 
146  char *name;
147 
151  struct ClientCtx *head;
152 
156  struct ClientCtx *tail;
157 
161  struct WBarrier *whead;
162 
166  struct WBarrier *wtail;
167 
172 
177 
181  unsigned int num_wbarriers;
182 
186  unsigned int num_wbarriers_reached;
187 
191  unsigned int num_wbarriers_inited;
192 
196  unsigned int nreached;
197 
201  unsigned int nslaves;
202 
206  uint8_t quorum;
207 
208 };
209 
210 
215 
219 static struct GNUNET_SERVICE_Handle *ctx;
220 
221 
228 static void
230 {
231  struct ClientCtx *ctx;
232 
235  &barrier->hash,
236  barrier));
237  while (NULL != (ctx = barrier->head))
238  {
240  barrier->tail,
241  ctx);
242  ctx->barrier = NULL;
243  }
244  GNUNET_free (barrier->name);
245  GNUNET_free (barrier);
246 }
247 
248 
254 static void
256 {
257  struct WBarrier *wrapper;
258 
259  while (NULL != (wrapper = barrier->whead))
260  {
263  barrier->wtail,
264  wrapper);
265  GNUNET_free (wrapper);
266  }
267 }
268 
269 
279 static void
281  const char *name,
283  const char *emsg)
284 {
285  struct GNUNET_MQ_Envelope *env;
287  size_t name_len;
288  size_t err_len;
289 
290  GNUNET_assert ( (NULL == emsg) ||
292  name_len = strlen (name) + 1;
293  err_len = ((NULL == emsg) ? 0 : (strlen (emsg) + 1));
294  env = GNUNET_MQ_msg_extra (msg,
295  name_len + err_len,
297  msg->status = htons (status);
298  msg->name_len = htons ((uint16_t) name_len - 1);
299  GNUNET_memcpy (msg->data,
300  name,
301  name_len);
302  GNUNET_memcpy (msg->data + name_len,
303  emsg,
304  err_len);
306  env);
307 }
308 
309 
317 static void
319  const char *emsg)
320 {
321  GNUNET_assert (0 != barrier->status);
322  send_client_status_msg (barrier->mc,
323  barrier->name,
324  barrier->status,
325  emsg);
326 }
327 
328 
335 static int
337  const struct GNUNET_TESTBED_BarrierWait *msg)
338 {
339  return GNUNET_OK; /* always well-formed */
340 }
341 
342 
354 static void
356  const struct GNUNET_TESTBED_BarrierWait *msg)
357 {
358  struct ClientCtx *client_ctx = cls;
359  struct Barrier *barrier;
360  char *name;
361  struct GNUNET_HashCode key;
362  size_t name_len;
363  uint16_t msize;
364 
365  msize = ntohs (msg->header.size);
366  if (NULL == barrier_map)
367  {
368  GNUNET_break (0);
369  GNUNET_SERVICE_client_drop (client_ctx->client);
370  return;
371  }
372  name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierWait);
373  name = GNUNET_malloc (name_len + 1);
374  name[name_len] = '\0';
375  GNUNET_memcpy (name,
376  msg->name,
377  name_len);
378  LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n",
379  name);
380  GNUNET_CRYPTO_hash (name,
381  name_len,
382  &key);
383  GNUNET_free (name);
384  if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key)))
385  {
386  GNUNET_break (0);
387  GNUNET_SERVICE_client_drop (client_ctx->client);
388  return;
389  }
390  if (NULL != client_ctx->barrier)
391  {
392  GNUNET_break (0);
393  GNUNET_SERVICE_client_drop (client_ctx->client);
394  return;
395  }
396  client_ctx->barrier = barrier;
398  barrier->tail,
399  client_ctx);
400  barrier->nreached++;
401  if ( (barrier->num_wbarriers_reached == barrier->num_wbarriers) &&
402  (LOCAL_QUORUM_REACHED (barrier)) )
403  {
405  send_barrier_status_msg (barrier,
406  NULL);
407  }
409 }
410 
411 
420 static void *
421 connect_cb (void *cls,
423  struct GNUNET_MQ_Handle *mq)
424 {
425  struct ClientCtx *client_ctx;
426 
427  LOG_DEBUG ("Client connected to testbed-barrier service\n");
428  client_ctx = GNUNET_new (struct ClientCtx);
429  client_ctx->client = client;
430  return client_ctx;
431 }
432 
433 
442 static void
443 disconnect_cb (void *cls,
445  void *app_ctx)
446 {
447  struct ClientCtx *client_ctx = app_ctx;
448  struct Barrier *barrier = client_ctx->barrier;
449 
450  if (NULL != barrier)
451  {
453  barrier->tail,
454  client_ctx);
455  client_ctx->barrier = NULL;
456  }
457  GNUNET_free (client_ctx);
458  LOG_DEBUG ("Client disconnected from testbed-barrier service\n");
459 }
460 
461 
467 void
469 {
470  struct GNUNET_MQ_MessageHandler message_handlers[] = {
471  GNUNET_MQ_hd_var_size (barrier_wait,
474  NULL),
476  };
477 
478  LOG_DEBUG ("Launching testbed-barrier service\n");
479  barrier_map = GNUNET_CONTAINER_multihashmap_create (3,
480  GNUNET_YES);
481  ctx = GNUNET_SERVICE_start ("testbed-barrier",
482  cfg,
483  &connect_cb,
484  &disconnect_cb,
485  NULL,
486  message_handlers);
487 }
488 
489 
500 static int
502  const struct GNUNET_HashCode *key,
503  void *value)
504 {
505  struct Barrier *barrier = value;
506 
507  GNUNET_assert (NULL != barrier);
508  cancel_wrappers (barrier);
509  remove_barrier (barrier);
510  return GNUNET_YES;
511 }
512 
513 
517 void
519 {
520  GNUNET_assert (NULL != barrier_map);
524  NULL));
526  GNUNET_assert (NULL != ctx);
527  GNUNET_SERVICE_stop (ctx);
528 }
529 
530 
544 static void
546  const char *name,
547  struct GNUNET_TESTBED_Barrier *b_,
549  const char *emsg)
550 {
551  struct WBarrier *wrapper = cls;
552  struct Barrier *barrier = wrapper->barrier;
553 
554  GNUNET_assert (b_ == wrapper->hbarrier);
555  switch (status)
556  {
559  "Initialising barrier `%s' failed at a sub-controller: %s\n",
560  barrier->name,
561  (NULL != emsg) ? emsg : "NULL");
562  cancel_wrappers (barrier);
563  if (NULL == emsg)
564  emsg = "Initialisation failed at a sub-controller";
566  send_barrier_status_msg (barrier, emsg);
567  return;
570  {
571  GNUNET_break_op (0);
572  return;
573  }
574  barrier->num_wbarriers_reached++;
575  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
576  && (LOCAL_QUORUM_REACHED (barrier)))
577  {
579  send_barrier_status_msg (barrier, NULL);
580  }
581  return;
583  if (0 != barrier->status)
584  {
585  GNUNET_break_op (0);
586  return;
587  }
588  barrier->num_wbarriers_inited++;
589  if (barrier->num_wbarriers_inited == barrier->num_wbarriers)
590  {
592  send_barrier_status_msg (barrier, NULL);
593  }
594  return;
595  }
596 }
597 
598 
605 static void
607 {
608  struct Barrier *barrier = cls;
609 
610  cancel_wrappers (barrier);
612  send_barrier_status_msg (barrier,
613  "Timedout while propagating barrier initialisation\n");
614  remove_barrier (barrier);
615 }
616 
617 
618 
626 int
628  const struct GNUNET_TESTBED_BarrierInit *msg)
629 {
630  return GNUNET_OK; /* always well-formed */
631 }
632 
633 
645 void
647  const struct GNUNET_TESTBED_BarrierInit *msg)
648 {
649  struct GNUNET_SERVICE_Client *client = cls;
650  char *name;
651  struct Barrier *barrier;
652  struct Slave *slave;
653  struct WBarrier *wrapper;
654  struct GNUNET_HashCode hash;
655  size_t name_len;
656  unsigned int cnt;
657  uint16_t msize;
658 
659  if (NULL == GST_context)
660  {
661  GNUNET_break_op (0);
663  return;
664  }
665  if (client != GST_context->client)
666  {
667  GNUNET_break_op (0);
669  return;
670  }
671  msize = ntohs (msg->header.size);
672  name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit);
673  name = GNUNET_malloc (name_len + 1);
674  GNUNET_memcpy (name, msg->name, name_len);
675  GNUNET_CRYPTO_hash (name, name_len, &hash);
676  LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n",
677  name);
678  if (GNUNET_YES ==
680  &hash))
681  {
682  send_client_status_msg (client,
683  name,
685  "A barrier with the same name already exists");
686  GNUNET_free (name);
688  return;
689  }
690  barrier = GNUNET_new (struct Barrier);
691  barrier->hash = hash;
692  barrier->quorum = msg->quorum;
693  barrier->name = name;
694  barrier->mc = client;
697  &barrier->hash,
698  barrier,
701  /* Propagate barrier init to subcontrollers */
702  for (cnt = 0; cnt < GST_slave_list_size; cnt++)
703  {
704  if (NULL == (slave = GST_slave_list[cnt]))
705  continue;
706  if (NULL == slave->controller)
707  {
708  GNUNET_break (0);/* May happen when we are connecting to the controller */
709  continue;
710  }
711  wrapper = GNUNET_new (struct WBarrier);
712  wrapper->barrier = barrier;
713  wrapper->controller = slave->controller;
715  barrier->wtail,
716  wrapper);
717  barrier->num_wbarriers++;
718  wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (wrapper->controller,
719  barrier->name,
720  barrier->quorum,
722  wrapper,
723  GNUNET_NO);
724  }
725  if (NULL == barrier->whead) /* No further propagation */
726  {
728  LOG_DEBUG ("Sending GNUNET_TESTBED_BARRIERSTATUS_INITIALISED for barrier `%s'\n",
729  barrier->name);
730  send_barrier_status_msg (barrier, NULL);
731  }else
734  barrier);
735 }
736 
737 
745 int
747  const struct GNUNET_TESTBED_BarrierCancel *msg)
748 {
749  return GNUNET_OK; /* all are well-formed */
750 }
751 
752 
764 void
766  const struct GNUNET_TESTBED_BarrierCancel *msg)
767 {
768  struct GNUNET_SERVICE_Client *client = cls;
769  char *name;
770  struct Barrier *barrier;
771  struct GNUNET_HashCode hash;
772  size_t name_len;
773  uint16_t msize;
774 
775  if (NULL == GST_context)
776  {
777  GNUNET_break_op (0);
779  return;
780  }
781  if (client != GST_context->client)
782  {
783  GNUNET_break_op (0);
785  return;
786  }
787  msize = ntohs (msg->header.size);
788  name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierCancel);
789  name = GNUNET_malloc (name_len + 1);
790  GNUNET_memcpy (name,
791  msg->name,
792  name_len);
793  LOG_DEBUG ("Received BARRIER_CANCEL for barrier `%s'\n",
794  name);
795  GNUNET_CRYPTO_hash (name,
796  name_len,
797  &hash);
798  if (GNUNET_NO ==
800  &hash))
801  {
802  GNUNET_break_op (0);
804  return;
805  }
806  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
807  &hash);
808  GNUNET_assert (NULL != barrier);
809  cancel_wrappers (barrier);
810  remove_barrier (barrier);
812 }
813 
814 
822 int
824  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
825 {
826  uint16_t msize;
827  uint16_t name_len;
828  const char *name;
830 
831  msize = ntohs (msg->header.size) - sizeof (*msg);
832  status = ntohs (msg->status);
834  {
835  GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED
836  status message this way */
837  return GNUNET_SYSERR;
838  }
839  name = msg->data;
840  name_len = ntohs (msg->name_len);
841  if ((name_len + 1) != msize)
842  {
843  GNUNET_break_op (0);
844  return GNUNET_SYSERR;
845  }
846  if ('\0' != name[name_len])
847  {
848  GNUNET_break_op (0);
849  return GNUNET_SYSERR;
850  }
851  return GNUNET_OK;
852 }
853 
854 
863 void
865  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
866 {
867  struct GNUNET_SERVICE_Client *client = cls;
868  struct Barrier *barrier;
869  struct ClientCtx *client_ctx;
870  struct WBarrier *wrapper;
871  const char *name;
872  struct GNUNET_HashCode key;
873  uint16_t name_len;
874  struct GNUNET_MQ_Envelope *env;
875 
876  if (NULL == GST_context)
877  {
878  GNUNET_break_op (0);
880  return;
881  }
882  if (client != GST_context->client)
883  {
884  GNUNET_break_op (0);
886  return;
887  }
888  name = msg->data;
889  name_len = ntohs (msg->name_len);
890  LOG_DEBUG ("Received BARRIER_STATUS for barrier `%s'\n",
891  name);
892  GNUNET_CRYPTO_hash (name,
893  name_len,
894  &key);
895  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
896  &key);
897  if (NULL == barrier)
898  {
899  GNUNET_break_op (0);
901  return;
902  }
904  for(client_ctx = barrier->head; NULL != client_ctx; client_ctx = client_ctx->next) /* Notify peers */
905  {
906  env = GNUNET_MQ_msg_copy (&msg->header);
908  env);
909  }
914  for (wrapper = barrier->whead; NULL != wrapper; wrapper = wrapper->next)
915  {
917  GNUNET_copy_message (&msg->header));
918  }
919 }
920 
921 /* 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:653
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:194
char name[0]
The name of the barrier they have reached.
Definition: testbed.h:901
Message to cancel a barrier.
Definition: testbed.h:845
Handle to a service.
Definition: service.c:116
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:877
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
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.
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:2157
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:867
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:850
Message sent from peers to the testbed-barrier service to indicate that they have reached a barrier a...
Definition: testbed.h:891
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:872
Handle to a client that is connected to a service.
Definition: service.c:249
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:1246
#define GNUNET_memcpy(dst, src, n)
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:855
void GNUNET_TESTBED_barrier_cancel(struct GNUNET_TESTBED_Barrier *barrier)
Cancel a barrier.
Definition: testbed_api.c:2459
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:2193
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:279
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:2618
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:2375
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:79
char data[0]
the barrier name (0-terminated) concatenated with an error message (0-terminated) if the status were ...
Definition: testbed.h:883
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:1331
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:828
#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:85
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:85
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:134
uint8_t quorum
The quorum percentage needed for crossing the barrier.
Definition: testbed.h:833
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:896
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:80
Message for signalling status changes of a barrier.
Definition: testbed.h:862
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:353
char name[0]
name of the barrier.
Definition: testbed.h:838
#define LOG_DEBUG(msg)
Message to initialise a barrier.
Definition: testbed.h:823
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:2533
#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.