diff options
author | LRN <lrn1986@gmail.com> | 2013-03-13 17:49:26 +0000 |
---|---|---|
committer | LRN <lrn1986@gmail.com> | 2013-03-13 17:49:26 +0000 |
commit | 405f776bc08486af4edb80e18149c0829732b347 (patch) | |
tree | d5fc635a51641dec6b53cb2540276f34ae8f6210 /src/arm/test_exponential_backoff.c | |
parent | 3ceae682287492ecc768aea5c4c463216a35774d (diff) | |
download | gnunet-405f776bc08486af4edb80e18149c0829732b347.tar.gz gnunet-405f776bc08486af4edb80e18149c0829732b347.zip |
All-encompassing ARM update
Diffstat (limited to 'src/arm/test_exponential_backoff.c')
-rw-r--r-- | src/arm/test_exponential_backoff.c | 265 |
1 files changed, 128 insertions, 137 deletions
diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c index 3395139ea..8a0dba117 100644 --- a/src/arm/test_exponential_backoff.c +++ b/src/arm/test_exponential_backoff.c | |||
@@ -43,14 +43,20 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
43 | 43 | ||
44 | static struct GNUNET_ARM_Handle *arm; | 44 | static struct GNUNET_ARM_Handle *arm; |
45 | 45 | ||
46 | static struct GNUNET_ARM_MonitorHandle *mon; | ||
47 | |||
46 | static int ok = 1; | 48 | static int ok = 1; |
47 | 49 | ||
50 | static int phase = 0; | ||
51 | |||
48 | static int trialCount; | 52 | static int trialCount; |
49 | 53 | ||
50 | static struct GNUNET_TIME_Absolute startedWaitingAt; | 54 | static struct GNUNET_TIME_Absolute startedWaitingAt; |
51 | 55 | ||
52 | struct GNUNET_TIME_Relative waitedFor; | 56 | struct GNUNET_TIME_Relative waitedFor; |
53 | 57 | ||
58 | struct GNUNET_TIME_Relative waitedFor_prev; | ||
59 | |||
54 | #if LOG_BACKOFF | 60 | #if LOG_BACKOFF |
55 | static FILE *killLogFilePtr; | 61 | static FILE *killLogFilePtr; |
56 | 62 | ||
@@ -97,11 +103,8 @@ struct ShutdownContext | |||
97 | 103 | ||
98 | /** | 104 | /** |
99 | * Handler receiving response to service shutdown requests. | 105 | * Handler receiving response to service shutdown requests. |
100 | * First call with NULL: service misbehaving, or something. | 106 | * We expect it to be called with NULL, since the service that |
101 | * First call with GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN: | 107 | * we are shutting down will just die without replying. |
102 | * - service will shutdown | ||
103 | * Second call with NULL: | ||
104 | * - service has now really shut down. | ||
105 | * | 108 | * |
106 | * @param cls closure | 109 | * @param cls closure |
107 | * @param msg NULL, indicating socket closure. | 110 | * @param msg NULL, indicating socket closure. |
@@ -111,7 +114,7 @@ service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
111 | { | 114 | { |
112 | struct ShutdownContext *shutdown_ctx = cls; | 115 | struct ShutdownContext *shutdown_ctx = cls; |
113 | 116 | ||
114 | if (msg == NULL) | 117 | if (NULL == msg) |
115 | { | 118 | { |
116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); | 119 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); |
117 | if (shutdown_ctx->cont != NULL) | 120 | if (shutdown_ctx->cont != NULL) |
@@ -122,29 +125,7 @@ service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
122 | GNUNET_free (shutdown_ctx); | 125 | GNUNET_free (shutdown_ctx); |
123 | return; | 126 | return; |
124 | } | 127 | } |
125 | GNUNET_assert (ntohs (msg->size) == | 128 | GNUNET_assert (0); |
126 | sizeof (struct GNUNET_MessageHeader)); | ||
127 | switch (ntohs (msg->type)) | ||
128 | { | ||
129 | case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN: | ||
130 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
131 | "Received confirmation for service shutdown.\n"); | ||
132 | shutdown_ctx->confirmed = GNUNET_YES; | ||
133 | GNUNET_CLIENT_receive (shutdown_ctx->sock, | ||
134 | &service_shutdown_handler, shutdown_ctx, | ||
135 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
136 | break; | ||
137 | default: /* Fall through */ | ||
138 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
139 | "Service shutdown refused!\n"); | ||
140 | if (shutdown_ctx->cont != NULL) | ||
141 | shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES); | ||
142 | |||
143 | GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); | ||
144 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock); | ||
145 | GNUNET_free (shutdown_ctx); | ||
146 | break; | ||
147 | } | ||
148 | } | 129 | } |
149 | 130 | ||
150 | 131 | ||
@@ -183,25 +164,27 @@ write_shutdown (void *cls, size_t size, void *buf) | |||
183 | struct ShutdownContext *shutdown_ctx = cls; | 164 | struct ShutdownContext *shutdown_ctx = cls; |
184 | 165 | ||
185 | if (size < sizeof (struct GNUNET_MessageHeader)) | 166 | if (size < sizeof (struct GNUNET_MessageHeader)) |
186 | { | 167 | { |
187 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 168 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
188 | _("Failed to transmit shutdown request to client.\n")); | 169 | _("Failed to transmit shutdown request to client.\n")); |
189 | shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); | 170 | FPRINTF (stderr, "%s", "Failed to send a shutdown request\n"); |
190 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock); | 171 | shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); |
191 | GNUNET_free (shutdown_ctx); | 172 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock); |
192 | return 0; /* client disconnected */ | 173 | GNUNET_free (shutdown_ctx); |
193 | } | 174 | return 0; /* client disconnected */ |
175 | } | ||
194 | 176 | ||
195 | GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, | 177 | GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, |
196 | shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); | 178 | shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); |
197 | shutdown_ctx->cancel_task = | 179 | shutdown_ctx->cancel_task = GNUNET_SCHEDULER_add_delayed ( |
198 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | 180 | GNUNET_TIME_absolute_get_remaining (shutdown_ctx->timeout), |
199 | (shutdown_ctx->timeout), | 181 | &service_shutdown_cancel, shutdown_ctx); |
200 | &service_shutdown_cancel, shutdown_ctx); | ||
201 | msg = (struct GNUNET_MessageHeader *) buf; | 182 | msg = (struct GNUNET_MessageHeader *) buf; |
202 | msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN); | 183 | msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_STOP); |
203 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | 184 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); |
204 | return sizeof (struct GNUNET_MessageHeader); | 185 | strcpy ((char *) &msg[1], "do-nothing"); |
186 | FPRINTF (stderr, "%s", "Sent a shutdown request\n"); | ||
187 | return sizeof (struct GNUNET_MessageHeader) + strlen ("do-nothing") + 1; | ||
205 | } | 188 | } |
206 | 189 | ||
207 | 190 | ||
@@ -219,7 +202,7 @@ write_shutdown (void *cls, size_t size, void *buf) | |||
219 | * | 202 | * |
220 | */ | 203 | */ |
221 | static void | 204 | static void |
222 | arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock, | 205 | do_nothing_service_shutdown (struct GNUNET_CLIENT_Connection *sock, |
223 | struct GNUNET_TIME_Relative timeout, | 206 | struct GNUNET_TIME_Relative timeout, |
224 | GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) | 207 | GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) |
225 | { | 208 | { |
@@ -231,125 +214,132 @@ arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock, | |||
231 | shutdown_ctx->sock = sock; | 214 | shutdown_ctx->sock = sock; |
232 | shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 215 | shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
233 | GNUNET_CLIENT_notify_transmit_ready (sock, | 216 | GNUNET_CLIENT_notify_transmit_ready (sock, |
234 | sizeof (struct GNUNET_MessageHeader), | 217 | sizeof (struct GNUNET_MessageHeader) + strlen ("do-nothing") + 1, |
235 | timeout, GNUNET_NO, &write_shutdown, | 218 | timeout, GNUNET_NO, &write_shutdown, |
236 | shutdown_ctx); | 219 | shutdown_ctx); |
237 | } | 220 | } |
238 | 221 | ||
239 | |||
240 | static void | ||
241 | arm_notify_stop (void *cls, enum GNUNET_ARM_ProcessStatus status) | ||
242 | { | ||
243 | GNUNET_assert ( (status == GNUNET_ARM_PROCESS_DOWN) || | ||
244 | (status == GNUNET_ARM_PROCESS_ALREADY_DOWN) ); | ||
245 | #if START_ARM | ||
246 | GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, NULL, NULL); | ||
247 | #endif | ||
248 | } | ||
249 | |||
250 | |||
251 | static void | 222 | static void |
252 | kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc); | 223 | kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc); |
253 | 224 | ||
254 | |||
255 | static void | 225 | static void |
256 | do_nothing_notify (void *cls, enum GNUNET_ARM_ProcessStatus status) | 226 | shutdown_cont (void *cls, int reason) |
257 | { | ||
258 | GNUNET_assert (status == GNUNET_ARM_PROCESS_STARTING); | ||
259 | ok = 1; | ||
260 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &kill_task, NULL); | ||
261 | } | ||
262 | |||
263 | static void | ||
264 | arm_notify (void *cls, enum GNUNET_ARM_ProcessStatus status) | ||
265 | { | 227 | { |
266 | GNUNET_assert (status == GNUNET_ARM_PROCESS_STARTING); | 228 | if (GNUNET_NO != reason) |
267 | GNUNET_ARM_start_service (arm, "do-nothing", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, TIMEOUT, &do_nothing_notify, | 229 | { |
268 | NULL); | 230 | /* Re-try shutdown */ |
231 | FPRINTF (stderr, "%s", "do-nothing didn't die, trying again\n"); | ||
232 | GNUNET_SCHEDULER_add_now (kill_task, NULL); | ||
233 | return; | ||
234 | } | ||
235 | startedWaitingAt = GNUNET_TIME_absolute_get (); | ||
236 | FPRINTF (stderr, "%s", "do-nothing is dead, starting the countdown\n"); | ||
269 | } | 237 | } |
270 | 238 | ||
271 | |||
272 | static void | 239 | static void |
273 | kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc); | 240 | kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc) |
274 | |||
275 | |||
276 | static void | ||
277 | do_nothing_restarted_notify_task (void *cls, | ||
278 | const struct GNUNET_SCHEDULER_TaskContext | ||
279 | *tc) | ||
280 | { | 241 | { |
281 | static char a; | 242 | static struct GNUNET_CLIENT_Connection *doNothingConnection = NULL; |
282 | |||
283 | trialCount++; | ||
284 | 243 | ||
244 | if (NULL != cbData) | ||
245 | { | ||
246 | waitedFor = GNUNET_TIME_absolute_get_duration (startedWaitingAt); | ||
247 | FPRINTF (stderr, "Waited for: %llu ms\n", waitedFor.rel_value); | ||
285 | #if LOG_BACKOFF | 248 | #if LOG_BACKOFF |
286 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 249 | FPRINTF (killLogFilePtr, "Waited for: %llu ms\n", |
287 | { | 250 | (unsigned long long) waitedFor.rel_value); |
288 | FPRINTF (killLogFilePtr, "%d.Reason is shutdown!\n", trialCount); | ||
289 | } | ||
290 | else if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0) | ||
291 | { | ||
292 | FPRINTF (killLogFilePtr, "%d.Reason is timeout!\n", trialCount); | ||
293 | } | ||
294 | else if ((tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE) != 0) | ||
295 | { | ||
296 | FPRINTF (killLogFilePtr, "%d.Service is running!\n", trialCount); | ||
297 | } | ||
298 | #endif | 251 | #endif |
299 | GNUNET_SCHEDULER_add_now (&kill_task, &a); | 252 | } |
253 | else | ||
254 | { | ||
255 | waitedFor.rel_value = 0; | ||
256 | } | ||
257 | /* Connect to the doNothing task */ | ||
258 | doNothingConnection = GNUNET_CLIENT_connect ("do-nothing", cfg); | ||
259 | GNUNET_assert (doNothingConnection != NULL); | ||
260 | if (trialCount == 12) | ||
261 | waitedFor_prev = waitedFor; | ||
262 | else if (trialCount == 13) | ||
263 | { | ||
264 | GNUNET_CLIENT_disconnect (doNothingConnection); | ||
265 | GNUNET_ARM_request_service_stop (arm, "do-nothing", TIMEOUT, NULL, NULL); | ||
266 | if (waitedFor_prev.rel_value >= waitedFor.rel_value) | ||
267 | ok = 9; | ||
268 | else | ||
269 | ok = 0; | ||
270 | trialCount += 1; | ||
271 | return; | ||
272 | } | ||
273 | trialCount += 1; | ||
274 | /* Use the created connection to kill the doNothingTask */ | ||
275 | do_nothing_service_shutdown (doNothingConnection, | ||
276 | TIMEOUT, &shutdown_cont, NULL); | ||
300 | } | 277 | } |
301 | 278 | ||
302 | |||
303 | static void | 279 | static void |
304 | do_test (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc) | 280 | trigger_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
305 | { | 281 | { |
306 | GNUNET_CLIENT_service_test ("do-nothing", cfg, TIMEOUT, | 282 | GNUNET_ARM_disconnect (arm); |
307 | &do_nothing_restarted_notify_task, NULL); | 283 | GNUNET_ARM_monitor_disconnect (mon); |
308 | } | 284 | } |
309 | 285 | ||
310 | 286 | ||
311 | static void | 287 | static void |
312 | shutdown_cont (void *cls, int reason) | 288 | arm_stop_cb (void *cls, struct GNUNET_ARM_Handle *h, enum GNUNET_ARM_RequestStatus status, const char *servicename, enum GNUNET_ARM_Result result) |
313 | { | 289 | { |
314 | trialCount++; | 290 | GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); |
315 | startedWaitingAt = GNUNET_TIME_absolute_get (); | 291 | GNUNET_break (result == GNUNET_ARM_RESULT_STOPPING); |
316 | GNUNET_SCHEDULER_add_delayed (waitedFor, &do_test, NULL); | 292 | FPRINTF (stderr, "%s", "ARM service stopped\n"); |
293 | GNUNET_SCHEDULER_add_now (trigger_disconnect, NULL); | ||
317 | } | 294 | } |
318 | 295 | ||
319 | 296 | void | |
320 | static void | 297 | srv_status (void *cls, struct GNUNET_ARM_MonitorHandle *mon, const char *service, enum GNUNET_ARM_ServiceStatus status) |
321 | kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
322 | { | 298 | { |
323 | static struct GNUNET_CLIENT_Connection *doNothingConnection = NULL; | 299 | FPRINTF (stderr, "Service %s is %u, phase %u\n", service, status, phase); |
324 | 300 | if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED) | |
325 | if (NULL != cbData) | 301 | { |
326 | { | 302 | phase++; |
327 | waitedFor = GNUNET_TIME_absolute_get_duration (startedWaitingAt); | 303 | GNUNET_ARM_request_service_start (arm, "do-nothing", |
328 | 304 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, TIMEOUT, NULL, NULL); | |
329 | #if LOG_BACKOFF | 305 | return; |
330 | FPRINTF (killLogFilePtr, "Waited for: %llu ms\n", | 306 | } |
331 | (unsigned long long) waitedFor.rel_value); | 307 | if (phase == 1) |
332 | #endif | 308 | { |
333 | } | 309 | GNUNET_break (status == GNUNET_ARM_SERVICE_STARTING); |
334 | else | 310 | GNUNET_break (0 == strcasecmp (service, "do-nothing")); |
311 | GNUNET_break (phase == 1); | ||
312 | FPRINTF (stderr, "%s", "do-nothing is starting\n"); | ||
313 | phase++; | ||
314 | ok = 1; | ||
315 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &kill_task, NULL); | ||
316 | } | ||
317 | else if ((phase == 2) && (strcasecmp ("do-nothing", service) == 0)) | ||
318 | { | ||
319 | /* We passively monitor ARM for status updates. ARM should tell us | ||
320 | * when do-nothing dies (no need to run a service upness test ourselves). | ||
321 | */ | ||
322 | if (status == GNUNET_ARM_SERVICE_STARTING) | ||
335 | { | 323 | { |
336 | waitedFor.rel_value = 0; | 324 | FPRINTF (stderr, "%s", "do-nothing is starting\n"); |
325 | GNUNET_SCHEDULER_add_now (kill_task, &ok); | ||
337 | } | 326 | } |
338 | /* Connect to the doNothing task */ | 327 | else if ((status == GNUNET_ARM_SERVICE_STOPPED) && (trialCount == 14)) |
339 | doNothingConnection = GNUNET_CLIENT_connect ("do-nothing", cfg); | ||
340 | GNUNET_assert (doNothingConnection != NULL); | ||
341 | if (trialCount == 12) | ||
342 | { | 328 | { |
343 | GNUNET_CLIENT_disconnect (doNothingConnection); | 329 | phase++; |
344 | GNUNET_ARM_stop_service (arm, "do-nothing", TIMEOUT, &arm_notify_stop, | 330 | GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL); |
345 | NULL); | ||
346 | ok = 0; | ||
347 | return; | ||
348 | } | 331 | } |
349 | /* Use the created connection to kill the doNothingTask */ | 332 | } |
350 | arm_service_shutdown (doNothingConnection, TIMEOUT, &shutdown_cont, NULL); | ||
351 | } | 333 | } |
352 | 334 | ||
335 | static void | ||
336 | arm_start_cb (void *cls, struct GNUNET_ARM_Handle *h, enum GNUNET_ARM_RequestStatus status, const char *servicename, enum GNUNET_ARM_Result result) | ||
337 | { | ||
338 | GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); | ||
339 | GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); | ||
340 | GNUNET_break (phase == 0); | ||
341 | FPRINTF (stderr, "Sent 'START' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); | ||
342 | } | ||
353 | 343 | ||
354 | static void | 344 | static void |
355 | task (void *cls, char *const *args, const char *cfgfile, | 345 | task (void *cls, char *const *args, const char *cfgfile, |
@@ -359,9 +349,8 @@ task (void *cls, char *const *args, const char *cfgfile, | |||
359 | cfg = c; | 349 | cfg = c; |
360 | if (NULL != cfgfile) | 350 | if (NULL != cfgfile) |
361 | { | 351 | { |
362 | if (GNUNET_OK != | 352 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", |
363 | GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG", | 353 | "CONFIG", &armconfig)) |
364 | &armconfig)) | ||
365 | { | 354 | { |
366 | GNUNET_CONFIGURATION_set_value_string ((struct GNUNET_CONFIGURATION_Handle | 355 | GNUNET_CONFIGURATION_set_value_string ((struct GNUNET_CONFIGURATION_Handle |
367 | *) cfg, "arm", "CONFIG", | 356 | *) cfg, "arm", "CONFIG", |
@@ -371,16 +360,18 @@ task (void *cls, char *const *args, const char *cfgfile, | |||
371 | GNUNET_free (armconfig); | 360 | GNUNET_free (armconfig); |
372 | } | 361 | } |
373 | 362 | ||
374 | arm = GNUNET_ARM_connect (cfg, NULL); | 363 | arm = GNUNET_ARM_alloc (cfg); |
364 | GNUNET_ARM_connect (arm, NULL, NULL); | ||
365 | mon = GNUNET_ARM_monitor_alloc (cfg); | ||
366 | GNUNET_ARM_monitor (mon, srv_status, NULL); | ||
375 | #if START_ARM | 367 | #if START_ARM |
376 | GNUNET_ARM_start_service (arm, "arm", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, GNUNET_TIME_UNIT_ZERO, &arm_notify, | 368 | GNUNET_ARM_request_service_start (arm, "arm", |
377 | NULL); | 369 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, GNUNET_TIME_UNIT_ZERO, arm_start_cb, NULL); |
378 | #else | 370 | #else |
379 | arm_do_nothing (NULL, GNUNET_YES); | 371 | arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_SERVICE_STARTING); |
380 | #endif | 372 | #endif |
381 | } | 373 | } |
382 | 374 | ||
383 | |||
384 | static int | 375 | static int |
385 | check () | 376 | check () |
386 | { | 377 | { |