GNUnet  0.11.x
testing_messenger_barrier.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2021 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  */
27 
29 {
30  unsigned int requirement;
32  void *cls;
33 
36 
38 };
39 
43  void *cb_cls)
44 {
45  if (0 == requirement)
46  return NULL;
47 
48  struct GNUNET_BarrierHandle *barrier = GNUNET_new(struct GNUNET_BarrierHandle);
49 
50  if (!barrier)
51  return NULL;
52 
53  barrier->requirement = requirement;
54  barrier->cb = cb;
55  barrier->cls = cb_cls;
56  barrier->head = NULL;
57  barrier->tail = NULL;
58  barrier->task = NULL;
59 
60  return barrier;
61 }
62 
63 static void
64 exit_status (struct GNUNET_BarrierHandle *barrier, int status);
65 
66 static void
68 {
70 }
71 
72 static void
74 {
76 }
77 
78 void
80 {
81  if ((!barrier) || (barrier->task))
82  return;
83 
84  barrier->task = GNUNET_SCHEDULER_add_now(cancel_barrier, barrier);
85 }
86 
88 {
90  void *cls;
91 
94 
96 };
97 
98 static void
99 exit_status (struct GNUNET_BarrierHandle *barrier, int status)
100 {
101  struct GNUNET_BarrierWaitHandle *waiting = barrier->head;
102  while (waiting)
103  {
104  struct GNUNET_BarrierWaitHandle *current = waiting;
105 
106  if (current->cb)
107  current->cb(current->cls, current, status);
108 
109  waiting = waiting->next;
110 
111  GNUNET_CONTAINER_DLL_remove(barrier->head, barrier->tail, current);
112  GNUNET_free(current);
113  }
114 
115  if (barrier->cb)
116  barrier->cb(barrier->cls, barrier, status);
117 
118  GNUNET_free(barrier);
119 }
120 
124  void *cb_cls)
125 {
126  if ((!barrier) || (0 == barrier->requirement))
127  return NULL;
128 
130 
131  if (!waiting)
132  return NULL;
133 
134  waiting->cb = cb;
135  waiting->cls = cb_cls;
136  waiting->prev = NULL;
137  waiting->next = NULL;
138  waiting->barrier = barrier;
139 
140  GNUNET_CONTAINER_DLL_insert_tail(barrier->head, barrier->tail, waiting);
141  barrier->requirement--;
142 
143  if ((barrier->requirement == 0) && (!barrier->task))
144  barrier->task = GNUNET_SCHEDULER_add_now(complete_barrier, barrier);
145 
146  return waiting;
147 }
148 
149 void
151 {
152  if (!waiting)
153  return;
154 
155  struct GNUNET_BarrierHandle *barrier = waiting->barrier;
156 
157  if (!barrier)
158  return;
159 
160  if ((barrier->requirement == 0) && (barrier->task))
161  {
162  GNUNET_SCHEDULER_cancel(barrier->task);
163  barrier->task = NULL;
164  }
165 
166  barrier->requirement++;
167  GNUNET_CONTAINER_DLL_remove(barrier->head, barrier->tail, waiting);
168 
169  GNUNET_free(waiting);
170 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_BarrierWaitHandle * next
GNUNET_BarrierStatusCallback cb
struct GNUNET_BarrierWaitHandle * prev
static void complete_barrier(void *cls)
struct GNUNET_BarrierWaitHandle * tail
GNUNET_BarrierWaitStatusCallback cb
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void(* GNUNET_BarrierStatusCallback)(void *cls, struct GNUNET_BarrierHandle *barrier, int status)
Functions of this type are to be given as callback argument to GNUNET_init_barrier().
struct GNUNET_BarrierWaitHandle * head
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
uint16_t status
See PRISM_STATUS_*-constants.
struct GNUNET_BarrierWaitHandle * GNUNET_wait_barrier(struct GNUNET_BarrierHandle *barrier, GNUNET_BarrierWaitStatusCallback cb, void *cb_cls)
Wait for a pseudo-barrier to be crossed.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_SCHEDULER_Task * task
void GNUNET_cancel_wait_barrier(struct GNUNET_BarrierWaitHandle *waiting)
Cancel a pseudo-barrier wait handle.
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_BarrierHandle * barrier
Pseudo-barriers for simple event handling.
static void exit_status(struct GNUNET_BarrierHandle *barrier, int status)
struct GNUNET_BarrierHandle * GNUNET_init_barrier(unsigned int requirement, GNUNET_BarrierStatusCallback cb, void *cb_cls)
Initialise a pseudo-barrier and call the given callback when the required amount of peers (requiremen...
void(* GNUNET_BarrierWaitStatusCallback)(void *cls, struct GNUNET_BarrierWaitHandle *waiting, int status)
Functions of this type are to be given as acallback argument to GNUNET_wait_barrier().
static void cancel_barrier(void *cls)
void GNUNET_cancel_barrier(struct GNUNET_BarrierHandle *barrier)
Cancel a pseudo-barrier.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972