diff options
Diffstat (limited to 'src/testbed/testbed_api_operations.c')
-rw-r--r-- | src/testbed/testbed_api_operations.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/src/testbed/testbed_api_operations.c b/src/testbed/testbed_api_operations.c index b897cb453..f609b1770 100644 --- a/src/testbed/testbed_api_operations.c +++ b/src/testbed/testbed_api_operations.c | |||
@@ -78,14 +78,24 @@ struct OperationQueue | |||
78 | */ | 78 | */ |
79 | enum OperationState | 79 | enum OperationState |
80 | { | 80 | { |
81 | /** | 81 | /** |
82 | * The operation is currently waiting for resources | 82 | * The operation is just created and is in initial state |
83 | */ | 83 | */ |
84 | OP_STATE_INIT, | ||
85 | |||
86 | /** | ||
87 | * The operation is currently waiting for resources | ||
88 | */ | ||
84 | OP_STATE_WAITING, | 89 | OP_STATE_WAITING, |
85 | 90 | ||
86 | /** | 91 | /** |
87 | * The operation has started | 92 | * The operation is ready to be started |
88 | */ | 93 | */ |
94 | OP_STATE_READY, | ||
95 | |||
96 | /** | ||
97 | * The operation has started | ||
98 | */ | ||
89 | OP_STATE_STARTED | 99 | OP_STATE_STARTED |
90 | }; | 100 | }; |
91 | 101 | ||
@@ -164,8 +174,7 @@ check_readiness (struct GNUNET_TESTBED_Operation *op) | |||
164 | { | 174 | { |
165 | unsigned int i; | 175 | unsigned int i; |
166 | 176 | ||
167 | if (GNUNET_SCHEDULER_NO_TASK != op->start_task_id) | 177 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == op->start_task_id); |
168 | return; | ||
169 | for (i = 0; i < op->nqueues; i++) | 178 | for (i = 0; i < op->nqueues; i++) |
170 | { | 179 | { |
171 | if (0 == op->queues[i]->active) | 180 | if (0 == op->queues[i]->active) |
@@ -175,6 +184,7 @@ check_readiness (struct GNUNET_TESTBED_Operation *op) | |||
175 | { | 184 | { |
176 | op->queues[i]->active--; | 185 | op->queues[i]->active--; |
177 | } | 186 | } |
187 | op->state = OP_STATE_READY; | ||
178 | op->start_task_id = GNUNET_SCHEDULER_add_now (&call_start, op); | 188 | op->start_task_id = GNUNET_SCHEDULER_add_now (&call_start, op); |
179 | } | 189 | } |
180 | 190 | ||
@@ -195,6 +205,7 @@ GNUNET_TESTBED_operation_create_ (void *cls, OperationStart start, | |||
195 | 205 | ||
196 | op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation)); | 206 | op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation)); |
197 | op->start = start; | 207 | op->start = start; |
208 | op->state = OP_STATE_INIT; | ||
198 | op->release = release; | 209 | op->release = release; |
199 | op->cb_cls = cls; | 210 | op->cb_cls = cls; |
200 | op->start_task_id = GNUNET_SCHEDULER_NO_TASK; | 211 | op->start_task_id = GNUNET_SCHEDULER_NO_TASK; |
@@ -236,13 +247,10 @@ GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue) | |||
236 | 247 | ||
237 | 248 | ||
238 | /** | 249 | /** |
239 | * Add an operation to a queue. An operation can be in multiple | 250 | * Add an operation to a queue. An operation can be in multiple queues at |
240 | * queues at once. Once all queues permit the operation to become | 251 | * once. Once the operation is inserted into all the queues |
241 | * active, the operation will be activated. The actual activation | 252 | * GNUNET_TESTBED_operation_begin_wait_() has to be called to actually start |
242 | * will occur in a separate task (thus allowing multiple queue | 253 | * waiting for the operation to become active. |
243 | * insertions to be made without having the first one instantly | ||
244 | * trigger the operation if the first queue has sufficient | ||
245 | * resources). | ||
246 | * | 254 | * |
247 | * @param queue queue to add the operation to | 255 | * @param queue queue to add the operation to |
248 | * @param operation operation to add to the queue | 256 | * @param operation operation to add to the queue |
@@ -262,6 +270,24 @@ GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, | |||
262 | sizeof (struct OperationQueue *) * | 270 | sizeof (struct OperationQueue *) * |
263 | (++operation->nqueues)); | 271 | (++operation->nqueues)); |
264 | operation->queues[operation->nqueues - 1] = queue; | 272 | operation->queues[operation->nqueues - 1] = queue; |
273 | } | ||
274 | |||
275 | |||
276 | /** | ||
277 | * Marks the given operation as waiting on the queues. Once all queues permit | ||
278 | * the operation to become active, the operation will be activated. The actual | ||
279 | * activation will occur in a separate task (thus allowing multiple queue | ||
280 | * insertions to be made without having the first one instantly trigger the | ||
281 | * operation if the first queue has sufficient resources). | ||
282 | * | ||
283 | * @param operation the operation to marks as waiting | ||
284 | */ | ||
285 | void | ||
286 | GNUNET_TESTBED_operation_begin_wait_ (struct GNUNET_TESTBED_Operation | ||
287 | *operation) | ||
288 | { | ||
289 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == operation->start_task_id); | ||
290 | operation->state = OP_STATE_WAITING; | ||
265 | check_readiness (operation); | 291 | check_readiness (operation); |
266 | } | 292 | } |
267 | 293 | ||
@@ -293,7 +319,7 @@ GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, | |||
293 | GNUNET_CONTAINER_DLL_remove (queue->head, queue->tail, entry); | 319 | GNUNET_CONTAINER_DLL_remove (queue->head, queue->tail, entry); |
294 | GNUNET_free (entry); | 320 | GNUNET_free (entry); |
295 | for (; NULL != entry2; entry2 = entry2->next) | 321 | for (; NULL != entry2; entry2 = entry2->next) |
296 | if (OP_STATE_STARTED != entry2->op->state) | 322 | if (OP_STATE_WAITING == entry2->op->state) |
297 | break; | 323 | break; |
298 | if (NULL == entry2) | 324 | if (NULL == entry2) |
299 | return; | 325 | return; |