aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing_api_cmd_barrier_reached.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_api_cmd_barrier_reached.c')
-rw-r--r--src/testing/testing_api_cmd_barrier_reached.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/testing/testing_api_cmd_barrier_reached.c b/src/testing/testing_api_cmd_barrier_reached.c
new file mode 100644
index 000000000..7e6f58fc1
--- /dev/null
+++ b/src/testing/testing_api_cmd_barrier_reached.c
@@ -0,0 +1,214 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2022 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
21/**
22 * @file testing/testing_api_cmd_barrier_reached.c
23 * @brief Command to signal barrier was reached.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testing_barrier.h"
29
30/**
31 * Struct with information for callbacks.
32 *
33 */
34struct BarrierReachedState
35{
36 /**
37 * Callback to write messages to the master loop.
38 *
39 */
40 TESTING_CMD_HELPER_write_cb write_message;
41
42 /**
43 * Context for our asynchronous completion.
44 */
45 struct GNUNET_TESTING_AsyncContext ac;
46
47 /**
48 * The label of this command.
49 */
50 const char *label;
51
52 /**
53 * The name of the barrier this commands wait (if finishing asynchronous) for or/and reaches.
54 */
55 const char *barrier_name;
56
57 /*
58 * The global numer of the node the cmd runs on.
59 */
60 unsigned int node_number;
61
62 /**
63 * If this command will block.
64 */
65 unsigned int asynchronous_finish;
66
67 /**
68 * Is this cmd running on the master loop.
69 */
70 unsigned int running_on_master;
71};
72
73
74/**
75 * Run the command.
76 *
77 * @param cls closure.
78 * @param is the interpreter state.
79 */
80static void
81barrier_reached_run (void *cls,
82 struct GNUNET_TESTING_Interpreter *is)
83{
84 struct BarrierReachedState *brs = cls;
85 struct GNUNET_TESTING_Barrier *barrier;
86 struct GNUNET_TESTING_Command *cmd;
87 size_t msg_length;
88 struct GNUNET_TESTING_CommandBarrierReached *msg;
89
90 barrier = GNUNET_TESTING_get_barrier (is, brs->barrier_name);
91 if (NULL == barrier)
92 {
93 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
94 barrier->shadow = GNUNET_YES;
95 barrier->name = brs->label;
96 GNUNET_TESTING_barrier_add (is, barrier);
97 }
98 barrier->reached++;
99 if (GNUNET_TESTING_can_barrier_advance (barrier))
100 {
101 cmd->asynchronous_finish = GNUNET_YES;
102 GNUNET_TESTING_finish_attached_cmds (is, barrier);
103 }
104 else if (GNUNET_NO == brs->asynchronous_finish)
105 {
106 cmd = GNUNET_TESTING_interpreter_get_current_command (is);
107 GNUNET_CONTAINER_DLL_insert (barrier->cmds_head,
108 barrier->cmds_tail,
109 cmd);
110 }
111 else
112 {
113 cmd->asynchronous_finish = GNUNET_YES;
114 }
115 if (GNUNET_NO == brs->running_on_master)
116 {
117 msg_length = sizeof(struct GNUNET_TESTING_CommandBarrierReached);
118 msg = GNUNET_new (struct GNUNET_TESTING_CommandBarrierReached);
119 msg->header.size = htons ((uint16_t) msg_length);
120 msg->header.type = htons(GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED);
121 msg->barrier_name = barrier->name;
122 msg->node_number = brs->node_number;
123 brs->write_message ((struct GNUNET_MessageHeader *) msg, msg_length);
124 }
125}
126
127
128/**
129 * Cleanup the state from a "barrier reached" CMD, and possibly
130 * cancel a pending operation thereof.
131 *
132 * @param cls closure.
133 */
134static void
135barrier_reached_cleanup (void *cls)
136{
137 struct BarrierReachedState *brs = cls;
138
139 GNUNET_free (brs);
140}
141
142
143/**
144 * Offer internal data from a "batch" CMD, to other commands.
145 *
146 * @param cls closure.
147 * @param[out] ret result.
148 * @param trait name of the trait.
149 * @param index index number of the object to offer.
150 * @return #GNUNET_OK on success.
151 */
152static enum GNUNET_GenericReturnValue
153barrier_reached_traits (void *cls,
154 const void **ret,
155 const char *trait,
156 unsigned int index)
157{
158 struct BarrierReachedState *brs = cls;
159 struct GNUNET_TESTING_AsyncContext *ac = &brs->ac;
160
161 struct GNUNET_TESTING_Trait traits[] = {
162 GNUNET_TESTING_make_trait_async_context ((const void *) ac),
163 GNUNET_TESTING_trait_end ()
164 };
165
166 return GNUNET_TESTING_get_trait (traits,
167 ret,
168 trait,
169 index);
170}
171
172
173/**
174 * Create command.
175 *
176 * @param label name for command.
177 * @param barrier_label The name of the barrier we wait for (if finishing asynchronous) and which will be reached.
178 * @param asynchronous_finish If GNUNET_YES this command will not block. Can be NULL.
179 * @param node_number The global numer of the node the cmd runs on.
180 * @param running_on_master Is this cmd running on the master loop.
181 * @param write_message Callback to write messages to the master loop.
182 * @return command.
183 */
184struct GNUNET_TESTING_Command
185GNUNET_TESTING_cmd_barrier_reached (
186 const char *label,
187 const char *barrier_label,
188 unsigned int asynchronous_finish,
189 unsigned int node_number,
190 unsigned int running_on_master,
191 TESTING_CMD_HELPER_write_cb write_message)
192{
193 struct BarrierReachedState *brs;
194
195 brs = GNUNET_new (struct BarrierReachedState);
196 brs->label = label;
197 brs->barrier_name = barrier_label;
198 brs->asynchronous_finish = asynchronous_finish;
199 brs->node_number = node_number;
200 brs->running_on_master = running_on_master;
201 brs->write_message = write_message;
202 {
203 struct GNUNET_TESTING_Command cmd = {
204 .cls = brs,
205 .label = label,
206 .run = &barrier_reached_run,
207 .ac = &brs->ac,
208 .cleanup = &barrier_reached_cleanup,
209 .traits = &barrier_reached_traits
210 };
211
212 return cmd;
213 }
214}