aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-03-08 14:24:01 +0100
committerChristian Grothoff <christian@grothoff.org>2018-03-08 14:24:01 +0100
commit43a0b73b24875052b70809c5ae4d6387551f8f53 (patch)
tree8f9dec295d56b69ea76705967b2737796f64e110 /src/util/scheduler.c
parent1051931d1de852b8c7750e1d02f1abb5b044483a (diff)
downloadgnunet-43a0b73b24875052b70809c5ae4d6387551f8f53.tar.gz
gnunet-43a0b73b24875052b70809c5ae4d6387551f8f53.zip
better error reporting from scheduler
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r--src/util/scheduler.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index e00ca444b..2ca078276 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -45,12 +45,12 @@
45/** 45/**
46 * Obtain trace information for all scheduler calls that schedule tasks. 46 * Obtain trace information for all scheduler calls that schedule tasks.
47 */ 47 */
48#define EXECINFO GNUNET_NO 48#define EXECINFO GNUNET_YES
49 49
50/** 50/**
51 * Check each file descriptor before adding 51 * Check each file descriptor before adding
52 */ 52 */
53#define DEBUG_FDS GNUNET_NO 53#define DEBUG_FDS GNUNET_YES
54 54
55/** 55/**
56 * Depth of the traces collected via EXECINFO. 56 * Depth of the traces collected via EXECINFO.
@@ -667,7 +667,7 @@ sighandler_shutdown ()
667} 667}
668 668
669 669
670void 670static void
671shutdown_if_no_lifeness () 671shutdown_if_no_lifeness ()
672{ 672{
673 struct GNUNET_SCHEDULER_Task *t; 673 struct GNUNET_SCHEDULER_Task *t;
@@ -688,8 +688,9 @@ shutdown_if_no_lifeness ()
688} 688}
689 689
690 690
691int 691static int
692select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context); 692select_loop (struct GNUNET_SCHEDULER_Handle *sh,
693 struct DriverContext *context);
693 694
694 695
695/** 696/**
@@ -723,7 +724,8 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
723 task_cls, 724 task_cls,
724 GNUNET_SCHEDULER_REASON_STARTUP, 725 GNUNET_SCHEDULER_REASON_STARTUP,
725 GNUNET_SCHEDULER_PRIORITY_DEFAULT); 726 GNUNET_SCHEDULER_PRIORITY_DEFAULT);
726 select_loop (sh, &context); 727 select_loop (sh,
728 &context);
727 GNUNET_SCHEDULER_driver_done (sh); 729 GNUNET_SCHEDULER_driver_done (sh);
728 GNUNET_free (driver); 730 GNUNET_free (driver);
729} 731}
@@ -2267,8 +2269,9 @@ void GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh)
2267} 2269}
2268 2270
2269 2271
2270int 2272static int
2271select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context) 2273select_loop (struct GNUNET_SCHEDULER_Handle *sh,
2274 struct DriverContext *context)
2272{ 2275{
2273 struct GNUNET_NETWORK_FDSet *rs; 2276 struct GNUNET_NETWORK_FDSet *rs;
2274 struct GNUNET_NETWORK_FDSet *ws; 2277 struct GNUNET_NETWORK_FDSet *ws;
@@ -2277,8 +2280,8 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2277 GNUNET_assert (NULL != context); 2280 GNUNET_assert (NULL != context);
2278 rs = GNUNET_NETWORK_fdset_create (); 2281 rs = GNUNET_NETWORK_fdset_create ();
2279 ws = GNUNET_NETWORK_fdset_create (); 2282 ws = GNUNET_NETWORK_fdset_create ();
2280 while (NULL != context->scheduled_head || 2283 while ( (NULL != context->scheduled_head) ||
2281 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != context->timeout.abs_value_us) 2284 (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != context->timeout.abs_value_us) )
2282 { 2285 {
2283 LOG (GNUNET_ERROR_TYPE_DEBUG, 2286 LOG (GNUNET_ERROR_TYPE_DEBUG,
2284 "select timeout = %s\n", 2287 "select timeout = %s\n",
@@ -2286,8 +2289,10 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2286 2289
2287 GNUNET_NETWORK_fdset_zero (rs); 2290 GNUNET_NETWORK_fdset_zero (rs);
2288 GNUNET_NETWORK_fdset_zero (ws); 2291 GNUNET_NETWORK_fdset_zero (ws);
2289 struct Scheduled *pos; 2292
2290 for (pos = context->scheduled_head; NULL != pos; pos = pos->next) 2293 for (struct Scheduled *pos = context->scheduled_head;
2294 NULL != pos;
2295 pos = pos->next)
2291 { 2296 {
2292 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et)) 2297 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et))
2293 { 2298 {
@@ -2320,12 +2325,16 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2320 if (errno == EINTR) 2325 if (errno == EINTR)
2321 continue; 2326 continue;
2322 2327
2323 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "select"); 2328 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
2329 "select");
2324#ifndef MINGW 2330#ifndef MINGW
2325#if USE_LSOF 2331#if USE_LSOF
2326 char lsof[512]; 2332 char lsof[512];
2327 2333
2328 snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid ()); 2334 snprintf (lsof,
2335 sizeof (lsof),
2336 "lsof -p %d",
2337 getpid ());
2329 (void) close (1); 2338 (void) close (1);
2330 (void) dup2 (2, 1); 2339 (void) dup2 (2, 1);
2331 if (0 != system (lsof)) 2340 if (0 != system (lsof))
@@ -2334,15 +2343,22 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2334#endif 2343#endif
2335#endif 2344#endif
2336#if DEBUG_FDS 2345#if DEBUG_FDS
2337 struct Scheduled *s; 2346 for (struct Scheduled *s = context->scheduled_head;
2338 for (s = context->scheduled_head; NULL != s; s = s->next) 2347 NULL != s;
2348 s = s->next)
2339 { 2349 {
2340 int flags = fcntl (s->fdi->sock, F_GETFD); 2350 int flags = fcntl (s->fdi->sock,
2341 if ((flags == -1) && (errno == EBADF)) 2351 F_GETFD);
2352
2353 if ( (flags == -1) &&
2354 (EBADF == errno) )
2342 { 2355 {
2343 LOG (GNUNET_ERROR_TYPE_ERROR, 2356 LOG (GNUNET_ERROR_TYPE_ERROR,
2344 "Got invalid file descriptor %d!\n", 2357 "Got invalid file descriptor %d!\n",
2345 s->fdi->sock); 2358 s->fdi->sock);
2359#if EXECINFO
2360 dump_backtrace (s->task);
2361#endif
2346 } 2362 }
2347 } 2363 }
2348#endif 2364#endif
@@ -2353,24 +2369,32 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2353 } 2369 }
2354 if (select_result > 0) 2370 if (select_result > 0)
2355 { 2371 {
2356 for (pos = context->scheduled_head; NULL != pos; pos = pos->next) 2372 for (struct Scheduled *pos = context->scheduled_head;
2373 NULL != pos;
2374 pos = pos->next)
2357 { 2375 {
2358 int is_ready = GNUNET_NO; 2376 int is_ready = GNUNET_NO;
2377
2359 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et) && 2378 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et) &&
2360 GNUNET_YES == GNUNET_NETWORK_fdset_test_native (rs, pos->fdi->sock)) 2379 GNUNET_YES ==
2380 GNUNET_NETWORK_fdset_test_native (rs,
2381 pos->fdi->sock))
2361 { 2382 {
2362 pos->fdi->et |= GNUNET_SCHEDULER_ET_IN; 2383 pos->fdi->et |= GNUNET_SCHEDULER_ET_IN;
2363 is_ready = GNUNET_YES; 2384 is_ready = GNUNET_YES;
2364 } 2385 }
2365 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et) && 2386 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et) &&
2366 GNUNET_YES == GNUNET_NETWORK_fdset_test_native (ws, pos->fdi->sock)) 2387 GNUNET_YES ==
2388 GNUNET_NETWORK_fdset_test_native (ws,
2389 pos->fdi->sock))
2367 { 2390 {
2368 pos->fdi->et |= GNUNET_SCHEDULER_ET_OUT; 2391 pos->fdi->et |= GNUNET_SCHEDULER_ET_OUT;
2369 is_ready = GNUNET_YES; 2392 is_ready = GNUNET_YES;
2370 } 2393 }
2371 if (GNUNET_YES == is_ready) 2394 if (GNUNET_YES == is_ready)
2372 { 2395 {
2373 GNUNET_SCHEDULER_task_ready (pos->task, pos->fdi); 2396 GNUNET_SCHEDULER_task_ready (pos->task,
2397 pos->fdi);
2374 } 2398 }
2375 } 2399 }
2376 } 2400 }
@@ -2386,7 +2410,7 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
2386} 2410}
2387 2411
2388 2412
2389int 2413static int
2390select_add (void *cls, 2414select_add (void *cls,
2391 struct GNUNET_SCHEDULER_Task *task, 2415 struct GNUNET_SCHEDULER_Task *task,
2392 struct GNUNET_SCHEDULER_FdInfo *fdi) 2416 struct GNUNET_SCHEDULER_FdInfo *fdi)