GNUnet  0.19.4
scheduler.c File Reference

schedule computations using continuation passing style More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "disk.h"
#include <inttypes.h>
Include dependency graph for scheduler.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_SCHEDULER_Handle
 Argument to be passed from the driver to GNUNET_SCHEDULER_do_work(). More...
 
struct  GNUNET_SCHEDULER_Task
 Entry in list of pending tasks. More...
 
struct  Scheduled
 A struct representing an event the select driver is waiting for. More...
 
struct  DriverContext
 Driver context used by GNUNET_SCHEDULER_run. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-scheduler", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)
 
#define PROFILE_DELAYS   GNUNET_NO
 Should we figure out which tasks are delayed for a while before they are run? (Consider using in combination with EXECINFO). More...
 
#define DELAY_THRESHOLD   GNUNET_TIME_UNIT_SECONDS
 Task that were in the queue for longer than this are reported if PROFILE_DELAYS is active. More...
 

Functions

void GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, void *new_select_cls)
 Sets the select function to use in the scheduler (scheduler_select). More...
 
static enum GNUNET_SCHEDULER_Priority check_priority (enum GNUNET_SCHEDULER_Priority p)
 Check that the given priority is legal (and return it). More...
 
struct GNUNET_TIME_Absolute get_timeout ()
 chooses the nearest timeout from all pending tasks, to be used to tell the driver the next wakeup time (using its set_wakeup callback) More...
 
static void remove_pass_end_marker ()
 
static void set_work_priority (enum GNUNET_SCHEDULER_Priority p)
 
static void queue_ready_task (struct GNUNET_SCHEDULER_Task *task)
 Put a task that is ready for execution into the ready queue. More...
 
void GNUNET_SCHEDULER_shutdown ()
 Request the shutdown of a scheduler. More...
 
static void dump_backtrace (struct GNUNET_SCHEDULER_Task *t)
 Output stack trace of task t. More...
 
static void destroy_task (struct GNUNET_SCHEDULER_Task *t)
 Destroy a task (release associated resources) More...
 
static void sighandler_pipe ()
 Signal handler called for SIGPIPE. More...
 
static void sighandler_shutdown (void)
 Signal handler called for signals that should cause us to shutdown. More...
 
static void shutdown_if_no_lifeness (void)
 
static int select_loop (struct GNUNET_SCHEDULER_Handle *sh, struct DriverContext *context)
 
void GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Initialize and run scheduler. More...
 
const struct GNUNET_SCHEDULER_TaskContextGNUNET_SCHEDULER_get_task_context ()
 Obtain the task context, giving the reason why the current task was started. More...
 
unsigned int GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
 Get information about the current load of this scheduler. More...
 
void init_fd_info (struct GNUNET_SCHEDULER_Task *t, const struct GNUNET_NETWORK_Handle *const *read_nh, unsigned int read_nh_len, const struct GNUNET_NETWORK_Handle *const *write_nh, unsigned int write_nh_len, const struct GNUNET_DISK_FileHandle *const *read_fh, unsigned int read_fh_len, const struct GNUNET_DISK_FileHandle *const *write_fh, unsigned int write_fh_len)
 
static void driver_add_multiple (struct GNUNET_SCHEDULER_Task *t)
 calls the given function func on each FdInfo related to t. More...
 
static void install_parent_control_handler (void *cls)
 
static void shutdown_pipe_cb (void *cls)
 
void * GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
 Cancel the task with the specified identifier. More...
 
static void init_backtrace (struct GNUNET_SCHEDULER_Task *t)
 Initialize backtrace data for task t. More...
 
void GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback task, void *task_cls, enum GNUNET_SCHEDULER_Reason reason, enum GNUNET_SCHEDULER_Priority priority)
 Continue the current execution with the given function. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run at the specified time. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified priority. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run at the specified time. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run as soon as possible. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run as soon as possible with the (transitive) ignore-shutdown flag either explicitly set or explicitly enabled. More...
 
static struct GNUNET_SCHEDULER_Taskadd_without_sets (struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, const struct GNUNET_NETWORK_Handle *read_nh, const struct GNUNET_NETWORK_Handle *write_nh, const struct GNUNET_DISK_FileHandle *read_fh, const struct GNUNET_DISK_FileHandle *write_fh, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when any of the specified file descriptor sets is ready. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready for reading. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified priority and to be run after the specified delay or when the specified file descriptor is ready for reading. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready for writing. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, struct GNUNET_NETWORK_Handle *fd, int on_read, int on_write, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready for reading. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready for writing. More...
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, const struct GNUNET_DISK_FileHandle *fd, int on_read, int on_write, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when the specified file descriptor is ready. More...
 
void extract_handles (const struct GNUNET_NETWORK_FDSet *fdset, const struct GNUNET_NETWORK_Handle ***ntarget, unsigned int *extracted_nhandles, const struct GNUNET_DISK_FileHandle ***ftarget, unsigned int *extracted_fhandles)
 
struct GNUNET_SCHEDULER_TaskGNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
 Schedule a new task to be run with a specified delay or when any of the specified file descriptor sets is ready. More...
 
void GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, struct GNUNET_SCHEDULER_FdInfo *fdi)
 Function used by event-loop implementations to signal the scheduler that a particular task is ready due to an event specified in the et field of fdi. More...
 
int GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh)
 Function called by external event loop implementations to tell the scheduler to run some of the tasks that are ready. More...
 
struct GNUNET_SCHEDULER_HandleGNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver)
 Function called by external event loop implementations to initialize the scheduler. More...
 
void GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh)
 Counter-part of GNUNET_SCHEDULER_driver_init. More...
 
static int select_add (void *cls, struct GNUNET_SCHEDULER_Task *task, struct GNUNET_SCHEDULER_FdInfo *fdi)
 
static int select_del (void *cls, struct GNUNET_SCHEDULER_Task *task)
 
static void select_set_wakeup (void *cls, struct GNUNET_TIME_Absolute dt)
 
struct GNUNET_SCHEDULER_DriverGNUNET_SCHEDULER_driver_select ()
 Obtain the driver for using select() as the event loop. More...
 
void GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid)
 Change the async scope for the currently executing task and (transitively) for all tasks scheduled by the current task after calling this function. More...
 

Variables

static struct GNUNET_SCHEDULER_Task pass_end_marker
 Placed at the end of a ready queue to indicate where a scheduler run pass ends. More...
 
static const struct GNUNET_SCHEDULER_Driverscheduler_driver
 The driver used for the event loop. More...
 
static struct GNUNET_SCHEDULER_Taskpending_head
 Head of list of tasks waiting for an event. More...
 
static struct GNUNET_SCHEDULER_Taskpending_tail
 Tail of list of tasks waiting for an event. More...
 
static struct GNUNET_SCHEDULER_Taskshutdown_head
 Head of list of tasks waiting for shutdown. More...
 
static struct GNUNET_SCHEDULER_Taskshutdown_tail
 Tail of list of tasks waiting for shutdown. More...
 
static struct GNUNET_SCHEDULER_Taskpending_timeout_head
 List of tasks waiting ONLY for a timeout event. More...
 
static struct GNUNET_SCHEDULER_Taskpending_timeout_tail
 List of tasks waiting ONLY for a timeout event. More...
 
static struct GNUNET_SCHEDULER_Taskpending_timeout_last
 Last inserted task waiting ONLY for a timeout event. More...
 
static struct GNUNET_SCHEDULER_Taskactive_task
 ID of the task that is running right now. More...
 
static struct GNUNET_SCHEDULER_Taskready_head [GNUNET_SCHEDULER_PRIORITY_COUNT]
 Head of list of tasks ready to run right now, grouped by importance. More...
 
static struct GNUNET_SCHEDULER_Taskready_tail [GNUNET_SCHEDULER_PRIORITY_COUNT]
 Tail of list of tasks ready to run right now, grouped by importance. More...
 
static struct GNUNET_SCHEDULER_Taskinstall_parent_control_task
 Task for installing parent control handlers (it might happen that the scheduler is shutdown before this task is executed, so GNUNET_SCHEDULER_shutdown must cancel it in that case) More...
 
static struct GNUNET_SCHEDULER_Taskshutdown_pipe_task
 Task for reading from a pipe that signal handlers will use to initiate shutdown. More...
 
static unsigned int ready_count
 Number of tasks on the ready list. More...
 
static enum GNUNET_SCHEDULER_Priority current_priority
 Priority of the task running right now. More...
 
static enum GNUNET_SCHEDULER_Priority max_priority_added
 Priority of the highest task added in the current select iteration. More...
 
static int current_lifeness
 Value of the 'lifeness' flag for the current task. More...
 
static enum GNUNET_SCHEDULER_Priority work_priority
 Priority used currently in GNUNET_SCHEDULER_do_work(). More...
 
static GNUNET_SCHEDULER_select scheduler_select
 Function to use as a select() in the scheduler. More...
 
static struct GNUNET_SCHEDULER_TaskContext tc
 Task context of the current task. More...
 
static void * scheduler_select_cls
 Closure for scheduler_select. More...
 
static struct GNUNET_DISK_PipeHandleshutdown_pipe_handle
 Pipe used to communicate shutdown via signal. More...
 
static pid_t my_pid
 Process ID of this process at the time we installed the various signal handlers. More...
 

Detailed Description

schedule computations using continuation passing style

Author
Christian Grothoff

Definition in file scheduler.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-scheduler", __VA_ARGS__)

Definition at line 32 of file scheduler.c.

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)
Value:
"util-scheduler", \
syscall)
#define GNUNET_log_from_strerror(level, component, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 34 of file scheduler.c.

◆ PROFILE_DELAYS

#define PROFILE_DELAYS   GNUNET_NO

Should we figure out which tasks are delayed for a while before they are run? (Consider using in combination with EXECINFO).

Definition at line 68 of file scheduler.c.

◆ DELAY_THRESHOLD

#define DELAY_THRESHOLD   GNUNET_TIME_UNIT_SECONDS

Task that were in the queue for longer than this are reported if PROFILE_DELAYS is active.

Definition at line 74 of file scheduler.c.

Function Documentation

◆ check_priority()

static enum GNUNET_SCHEDULER_Priority check_priority ( enum GNUNET_SCHEDULER_Priority  p)
static

Check that the given priority is legal (and return it).

Parameters
ppriority value to check
Returns
p on success, 0 on error

Definition at line 447 of file scheduler.c.

463 {
464  if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT))
465  return p;
466  GNUNET_assert (0);
467  return 0; /* make compiler happy */
468 }
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
@ GNUNET_SCHEDULER_PRIORITY_COUNT
Number of priorities (must be the last priority).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References scheduler_select, and scheduler_select_cls.

Referenced by add_without_sets(), GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_add_with_reason_and_priority(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_get_load(), and queue_ready_task().

Here is the caller graph for this function:

◆ get_timeout()

struct GNUNET_TIME_Absolute get_timeout ( )

chooses the nearest timeout from all pending tasks, to be used to tell the driver the next wakeup time (using its set_wakeup callback)

Definition at line 447 of file scheduler.c.

478 {
479  struct GNUNET_SCHEDULER_Task *pos;
480  struct GNUNET_TIME_Absolute now;
482 
483  pos = pending_timeout_head;
484  now = GNUNET_TIME_absolute_get ();
486  if (NULL != pos)
487  {
488  if (0 != pos->reason)
489  {
490  return now;
491  }
492  else
493  {
494  timeout = pos->timeout;
495  }
496  }
497  for (pos = pending_head; NULL != pos; pos = pos->next)
498  {
499  if (0 != pos->reason)
500  {
501  return now;
502  }
503  else if ((pos->timeout.abs_value_us !=
504  GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) &&
505  (timeout.abs_value_us > pos->timeout.abs_value_us))
506  {
507  timeout = pos->timeout;
508  }
509  }
510  return timeout;
511 }
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static struct GNUNET_SCHEDULER_Task * pending_head
Head of list of tasks waiting for an event.
Definition: scheduler.c:324
static struct GNUNET_SCHEDULER_Task * pending_timeout_head
List of tasks waiting ONLY for a timeout event.
Definition: scheduler.c:348
Entry in list of pending tasks.
Definition: scheduler.c:136
enum GNUNET_SCHEDULER_Reason reason
Why is the task ready? Set after task is added to ready queue.
Definition: scheduler.c:199
struct GNUNET_SCHEDULER_Task * next
This is a linked list.
Definition: scheduler.c:140
struct GNUNET_TIME_Absolute timeout
Absolute timeout value for the task, or GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout".
Definition: scheduler.c:185
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.

Referenced by GNUNET_SCHEDULER_do_work(), and GNUNET_SCHEDULER_driver_init().

Here is the caller graph for this function:

◆ remove_pass_end_marker()

static void remove_pass_end_marker ( )
static

Definition at line 513 of file scheduler.c.

514 {
516  {
519  &pass_end_marker);
521  }
522 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
@ GNUNET_NO
static struct GNUNET_SCHEDULER_Task * ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]
Tail of list of tasks ready to run right now, grouped by importance.
Definition: scheduler.c:379
static struct GNUNET_SCHEDULER_Task * ready_head[GNUNET_SCHEDULER_PRIORITY_COUNT]
Head of list of tasks ready to run right now, grouped by importance.
Definition: scheduler.c:373
static struct GNUNET_SCHEDULER_Task pass_end_marker
Placed at the end of a ready queue to indicate where a scheduler run pass ends.
Definition: scheduler.c:256
enum GNUNET_SCHEDULER_Priority priority
Task priority.
Definition: scheduler.c:204
int in_ready_list
Is this task in the ready list?
Definition: scheduler.c:230

References GNUNET_CONTAINER_DLL_remove, GNUNET_NO, GNUNET_SCHEDULER_Task::in_ready_list, pass_end_marker, GNUNET_SCHEDULER_Task::priority, ready_head, and ready_tail.

Referenced by GNUNET_SCHEDULER_do_work(), and set_work_priority().

Here is the caller graph for this function:

◆ set_work_priority()

static void set_work_priority ( enum GNUNET_SCHEDULER_Priority  p)
static

Definition at line 524 of file scheduler.c.

525 {
528  ready_tail[p],
529  &pass_end_marker);
532  work_priority = p;
533 }
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
@ GNUNET_YES
static void remove_pass_end_marker()
Definition: scheduler.c:513
static enum GNUNET_SCHEDULER_Priority work_priority
Priority used currently in GNUNET_SCHEDULER_do_work().
Definition: scheduler.c:420

References GNUNET_CONTAINER_DLL_insert_tail, GNUNET_YES, GNUNET_SCHEDULER_Task::in_ready_list, p, pass_end_marker, GNUNET_SCHEDULER_Task::priority, ready_head, ready_tail, remove_pass_end_marker(), and work_priority.

Referenced by GNUNET_SCHEDULER_do_work(), and queue_ready_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_ready_task()

static void queue_ready_task ( struct GNUNET_SCHEDULER_Task task)
static

Put a task that is ready for execution into the ready queue.

Parameters
tasktask ready for execution

Definition at line 541 of file scheduler.c.

542 {
544 
546  ready_tail[p],
547  task);
548  if (p > work_priority)
550  task->in_ready_list = GNUNET_YES;
551  ready_count++;
552 }
GNUNET_SCHEDULER_Priority
Valid task priorities.
static enum GNUNET_SCHEDULER_Priority check_priority(enum GNUNET_SCHEDULER_Priority p)
Check that the given priority is legal (and return it).
Definition: scheduler.c:462
static unsigned int ready_count
Number of tasks on the ready list.
Definition: scheduler.c:398
static void set_work_priority(enum GNUNET_SCHEDULER_Priority p)
Definition: scheduler.c:524

References check_priority(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_YES, GNUNET_SCHEDULER_Task::in_ready_list, p, GNUNET_SCHEDULER_Task::priority, ready_count, ready_head, ready_tail, set_work_priority(), and work_priority.

Referenced by GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_with_reason_and_priority(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_shutdown(), and GNUNET_SCHEDULER_task_ready().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dump_backtrace()

static void dump_backtrace ( struct GNUNET_SCHEDULER_Task t)
static

Output stack trace of task t.

Parameters
ttask to dump stack trace of

Definition at line 595 of file scheduler.c.

596 {
597 #if EXECINFO
598  for (unsigned int i = 0; i < t->num_backtrace_strings; i++)
600  "Task %p trace %u: %s\n",
601  t,
602  i,
603  t->backtrace_strings[i]);
604 #else
605  (void) t;
606 #endif
607 }
static struct GNUNET_SCHEDULER_Task * t
Main task.
@ GNUNET_ERROR_TYPE_WARNING
#define LOG(kind,...)
Definition: scheduler.c:32

References GNUNET_ERROR_TYPE_WARNING, LOG, and t.

Referenced by GNUNET_SCHEDULER_do_work(), init_backtrace(), and select_loop().

Here is the caller graph for this function:

◆ destroy_task()

static void destroy_task ( struct GNUNET_SCHEDULER_Task t)
static

Destroy a task (release associated resources)

Parameters
ttask to destroy

Definition at line 616 of file scheduler.c.

617 {
619  "destroying task %p\n",
620  t);
621 
622  if (GNUNET_YES == t->own_handles)
623  {
624  for (unsigned int i = 0; i != t->fds_len; ++i)
625  {
626  const struct GNUNET_NETWORK_Handle *fd = t->fds[i].fd;
627  const struct GNUNET_DISK_FileHandle *fh = t->fds[i].fh;
628  if (fd)
629  {
631  (struct GNUNET_NETWORK_Handle *) fd);
632  }
633  if (fh)
634  {
635  // FIXME: on WIN32 this is not enough! A function
636  // GNUNET_DISK_file_free_memory_only would be nice
637  GNUNET_free_nz ((void *) fh);
638  }
639  }
640  }
641  if (t->fds_len > 1)
642  {
643  GNUNET_array_grow (t->fds, t->fds_len, 0);
644  }
645 #if EXECINFO
646  GNUNET_free (t->backtrace_strings);
647 #endif
648  GNUNET_free (t);
649 }
static struct GNUNET_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition: network.c:565
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
handle to a socket
Definition: network.c:53
const struct GNUNET_DISK_FileHandle * fh
GNUnet file handle the event is about, matches sock, NULL if this is about a network socket or if no ...
const struct GNUNET_NETWORK_Handle * fd
GNUnet network socket the event is about, matches sock, NULL if this is about a file handle or if no ...
int own_handles
Do we own the network and file handles referenced by the FdInfo structs in the fds array.
Definition: scheduler.c:179
struct GNUNET_SCHEDULER_FdInfo * fds
Information about which FDs are ready for this task (and why).
Definition: scheduler.c:160
unsigned int fds_len
Size of the fds array.
Definition: scheduler.c:172

References GNUNET_DISK_FileHandle::fd, GNUNET_SCHEDULER_FdInfo::fd, GNUNET_NETWORK_Handle::fd, GNUNET_SCHEDULER_Task::fds, GNUNET_SCHEDULER_Task::fds_len, GNUNET_SCHEDULER_FdInfo::fh, fh, GNUNET_array_grow, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_free_nz, GNUNET_NETWORK_socket_free_memory_only_(), GNUNET_YES, LOG, GNUNET_SCHEDULER_Task::own_handles, and t.

Referenced by GNUNET_SCHEDULER_cancel(), and GNUNET_SCHEDULER_do_work().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sighandler_pipe()

static void sighandler_pipe ( )
static

Signal handler called for SIGPIPE.

Definition at line 667 of file scheduler.c.

668 {
669  return;
670 }

Referenced by GNUNET_SCHEDULER_driver_init().

Here is the caller graph for this function:

◆ sighandler_shutdown()

static void sighandler_shutdown ( void  )
static

Signal handler called for signals that should cause us to shutdown.

Definition at line 677 of file scheduler.c.

678 {
679  static char c;
680  int old_errno = errno; /* backup errno */
681 
682  if (getpid () != my_pid)
683  _exit (1); /* we have fork'ed since the signal handler was created,
684  * ignore the signal, see https://gnunet.org/vfork discussion */
688  &c, sizeof(c));
689  errno = old_errno;
690 }
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:686
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1617
@ GNUNET_DISK_PIPE_END_WRITE
The writing-end of a pipe.
static struct GNUNET_DISK_PipeHandle * shutdown_pipe_handle
Pipe used to communicate shutdown via signal.
Definition: scheduler.c:655
static pid_t my_pid
Process ID of this process at the time we installed the various signal handlers.
Definition: scheduler.c:661

References GNUNET_DISK_file_write(), GNUNET_DISK_PIPE_END_WRITE, GNUNET_DISK_pipe_handle(), my_pid, and shutdown_pipe_handle.

Referenced by GNUNET_SCHEDULER_driver_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_if_no_lifeness()

static void shutdown_if_no_lifeness ( void  )
static

Definition at line 694 of file scheduler.c.

695 {
696  struct GNUNET_SCHEDULER_Task *t;
697 
698  if (ready_count > 0)
699  return;
700  for (t = pending_head; NULL != t; t = t->next)
701  if (GNUNET_YES == t->lifeness)
702  return;
703  for (t = shutdown_head; NULL != t; t = t->next)
704  if (GNUNET_YES == t->lifeness)
705  return;
706  for (t = pending_timeout_head; NULL != t; t = t->next)
707  if (GNUNET_YES == t->lifeness)
708  return;
709  /* No lifeness! */
711 }
void GNUNET_SCHEDULER_shutdown()
Request the shutdown of a scheduler.
Definition: scheduler.c:562
static struct GNUNET_SCHEDULER_Task * shutdown_head
Head of list of tasks waiting for shutdown.
Definition: scheduler.c:334
int lifeness
Should the existence of this task in the queue be counted as reason to not shutdown the scheduler?
Definition: scheduler.c:220

References GNUNET_SCHEDULER_shutdown(), GNUNET_YES, GNUNET_SCHEDULER_Task::lifeness, GNUNET_SCHEDULER_Task::next, pending_head, pending_timeout_head, ready_count, shutdown_head, and t.

Referenced by GNUNET_SCHEDULER_do_work().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_loop()

static int select_loop ( struct GNUNET_SCHEDULER_Handle sh,
struct DriverContext context 
)
static

Definition at line 2306 of file scheduler.c.

2308 {
2309  struct GNUNET_NETWORK_FDSet *rs;
2310  struct GNUNET_NETWORK_FDSet *ws;
2311  int select_result;
2312 
2313  GNUNET_assert (NULL != context);
2316  while ((NULL != context->scheduled_head) ||
2317  (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us !=
2318  context->timeout.abs_value_us))
2319  {
2320  struct GNUNET_TIME_Relative time_remaining;
2321 
2323  "select timeout = %s\n",
2325 
2328 
2329  for (struct Scheduled *pos = context->scheduled_head;
2330  NULL != pos;
2331  pos = pos->next)
2332  {
2333  if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et))
2334  {
2335  GNUNET_NETWORK_fdset_set_native (rs, pos->fdi->sock);
2336  }
2337  if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et))
2338  {
2339  GNUNET_NETWORK_fdset_set_native (ws, pos->fdi->sock);
2340  }
2341  }
2342  time_remaining = GNUNET_TIME_absolute_get_remaining (context->timeout);
2343  if (0 < ready_count)
2344  time_remaining = GNUNET_TIME_UNIT_ZERO;
2345  if (NULL == scheduler_select)
2346  {
2347  select_result = GNUNET_NETWORK_socket_select (rs,
2348  ws,
2349  NULL,
2350  time_remaining);
2351  }
2352  else
2353  {
2354  select_result = scheduler_select (scheduler_select_cls,
2355  rs,
2356  ws,
2357  NULL,
2358  time_remaining);
2359  }
2360  if (select_result == GNUNET_SYSERR)
2361  {
2362  if (errno == EINTR)
2363  continue;
2364 
2366  "select");
2367 #if USE_LSOF
2368  char lsof[512];
2369 
2370  snprintf (lsof,
2371  sizeof(lsof),
2372  "lsof -p %d",
2373  getpid ());
2374  (void) close (1);
2375  (void) dup2 (2, 1);
2376  if (0 != system (lsof))
2378  "system");
2379 #endif
2380 #if DEBUG_FDS
2381  for (struct Scheduled *s = context->scheduled_head;
2382  NULL != s;
2383  s = s->next)
2384  {
2385  int flags = fcntl (s->fdi->sock,
2386  F_GETFD);
2387 
2388  if ((flags == -1) &&
2389  (EBADF == errno))
2390  {
2392  "Got invalid file descriptor %d!\n",
2393  s->fdi->sock);
2394 #if EXECINFO
2395  dump_backtrace (s->task);
2396 #endif
2397  }
2398  }
2399 #endif
2400  GNUNET_assert (0);
2403  return GNUNET_SYSERR;
2404  }
2405  if (select_result > 0)
2406  {
2407  for (struct Scheduled *pos = context->scheduled_head;
2408  NULL != pos;
2409  pos = pos->next)
2410  {
2411  int is_ready = GNUNET_NO;
2412 
2413  if ((0 != (GNUNET_SCHEDULER_ET_IN & pos->et)) &&
2414  (GNUNET_YES ==
2416  pos->fdi->sock)) )
2417  {
2418  pos->fdi->et |= GNUNET_SCHEDULER_ET_IN;
2419  is_ready = GNUNET_YES;
2420  }
2421  if ((0 != (GNUNET_SCHEDULER_ET_OUT & pos->et)) &&
2422  (GNUNET_YES ==
2424  pos->fdi->sock)) )
2425  {
2426  pos->fdi->et |= GNUNET_SCHEDULER_ET_OUT;
2427  is_ready = GNUNET_YES;
2428  }
2429  if (GNUNET_YES == is_ready)
2430  {
2431  GNUNET_SCHEDULER_task_ready (pos->task,
2432  pos->fdi);
2433  }
2434  }
2435  }
2437  {
2439  "scheduler has more tasks ready!\n");
2440  }
2441  }
2444  return GNUNET_OK;
2445 }
static struct SolverHandle * sh
static pa_context * context
Pulseaudio context.
@ GNUNET_OK
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1170
void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds)
Reset FD set (clears all file descriptors).
Definition: network.c:917
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1186
void GNUNET_NETWORK_fdset_set_native(struct GNUNET_NETWORK_FDSet *to, int nfd)
Set a native fd in a set.
Definition: network.c:1057
int GNUNET_NETWORK_fdset_test_native(const struct GNUNET_NETWORK_FDSet *to, int nfd)
Test native fd in a set.
Definition: network.c:1075
int GNUNET_NETWORK_socket_select(struct GNUNET_NETWORK_FDSet *rfds, struct GNUNET_NETWORK_FDSet *wfds, struct GNUNET_NETWORK_FDSet *efds, struct GNUNET_TIME_Relative timeout)
Check if sockets meet certain conditions.
Definition: network.c:1260
void GNUNET_SCHEDULER_task_ready(struct GNUNET_SCHEDULER_Task *task, struct GNUNET_SCHEDULER_FdInfo *fdi)
Function used by event-loop implementations to signal the scheduler that a particular task is ready d...
Definition: scheduler.c:1947
int GNUNET_SCHEDULER_do_work(struct GNUNET_SCHEDULER_Handle *sh)
Function called by external event loop implementations to tell the scheduler to run some of the tasks...
Definition: scheduler.c:1992
@ GNUNET_SCHEDULER_ET_OUT
Buffer available for writing.
@ GNUNET_SCHEDULER_ET_IN
Data available for reading.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
static void dump_backtrace(struct GNUNET_SCHEDULER_Task *t)
Output stack trace of task t.
Definition: scheduler.c:595
static GNUNET_SCHEDULER_select scheduler_select
Function to use as a select() in the scheduler.
Definition: scheduler.c:426
static void * scheduler_select_cls
Closure for scheduler_select.
Definition: scheduler.c:436
#define LOG_STRERROR(kind, syscall)
Definition: scheduler.c:34
collection of IO descriptors
Time for relative time used by GNUnet, in microseconds.
A struct representing an event the select driver is waiting for.
Definition: scheduler.c:263

References context, dump_backtrace(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_destroy(), GNUNET_NETWORK_fdset_set_native(), GNUNET_NETWORK_fdset_test_native(), GNUNET_NETWORK_fdset_zero(), GNUNET_NETWORK_socket_select(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_ET_IN, GNUNET_SCHEDULER_ET_OUT, GNUNET_SCHEDULER_task_ready(), GNUNET_STRINGS_absolute_time_to_string(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_ZERO, GNUNET_YES, LOG, LOG_STRERROR, GNUNET_SCHEDULER_Task::next, ready_count, scheduler_select, scheduler_select_cls, and sh.

Referenced by GNUNET_SCHEDULER_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_fd_info()

void init_fd_info ( struct GNUNET_SCHEDULER_Task t,
const struct GNUNET_NETWORK_Handle *const *  read_nh,
unsigned int  read_nh_len,
const struct GNUNET_NETWORK_Handle *const *  write_nh,
unsigned int  write_nh_len,
const struct GNUNET_DISK_FileHandle *const *  read_fh,
unsigned int  read_fh_len,
const struct GNUNET_DISK_FileHandle *const *  write_fh,
unsigned int  write_fh_len 
)

Definition at line 791 of file scheduler.c.

800 {
801  // FIXME: if we have exactly two network handles / exactly two file handles
802  // and they are equal, we can make one FdInfo with both
803  // GNUNET_SCHEDULER_ET_IN and GNUNET_SCHEDULER_ET_OUT set.
804  struct GNUNET_SCHEDULER_FdInfo *fdi;
805 
806  t->fds_len = read_nh_len + write_nh_len + read_fh_len + write_fh_len;
807  if (1 == t->fds_len)
808  {
809  fdi = &t->fdx;
810  t->fds = fdi;
811  if (1 == read_nh_len)
812  {
813  GNUNET_assert (NULL != read_nh);
814  GNUNET_assert (NULL != *read_nh);
815  fdi->fd = *read_nh;
816  fdi->et = GNUNET_SCHEDULER_ET_IN;
817  fdi->sock = GNUNET_NETWORK_get_fd (*read_nh);
818  t->read_fd = fdi->sock;
819  t->write_fd = -1;
820  }
821  else if (1 == write_nh_len)
822  {
823  GNUNET_assert (NULL != write_nh);
824  GNUNET_assert (NULL != *write_nh);
825  fdi->fd = *write_nh;
827  fdi->sock = GNUNET_NETWORK_get_fd (*write_nh);
828  t->read_fd = -1;
829  t->write_fd = fdi->sock;
830  }
831  else if (1 == read_fh_len)
832  {
833  GNUNET_assert (NULL != read_fh);
834  GNUNET_assert (NULL != *read_fh);
835  fdi->fh = *read_fh;
836  fdi->et = GNUNET_SCHEDULER_ET_IN;
837  fdi->sock = (*read_fh)->fd; // FIXME: does not work under WIN32
838  t->read_fd = fdi->sock;
839  t->write_fd = -1;
840  }
841  else
842  {
843  GNUNET_assert (NULL != write_fh);
844  GNUNET_assert (NULL != *write_fh);
845  fdi->fh = *write_fh;
847  fdi->sock = (*write_fh)->fd; // FIXME: does not work under WIN32
848  t->read_fd = -1;
849  t->write_fd = fdi->sock;
850  }
851  }
852  else
853  {
855  t->fds = fdi;
856  t->read_fd = -1;
857  t->write_fd = -1;
858  unsigned int i;
859  for (i = 0; i != read_nh_len; ++i)
860  {
861  fdi->fd = read_nh[i];
862  GNUNET_assert (NULL != fdi->fd);
863  fdi->et = GNUNET_SCHEDULER_ET_IN;
864  fdi->sock = GNUNET_NETWORK_get_fd (read_nh[i]);
865  ++fdi;
866  }
867  for (i = 0; i != write_nh_len; ++i)
868  {
869  fdi->fd = write_nh[i];
870  GNUNET_assert (NULL != fdi->fd);
872  fdi->sock = GNUNET_NETWORK_get_fd (write_nh[i]);
873  ++fdi;
874  }
875  for (i = 0; i != read_fh_len; ++i)
876  {
877  fdi->fh = read_fh[i];
878  GNUNET_assert (NULL != fdi->fh);
879  fdi->et = GNUNET_SCHEDULER_ET_IN;
880  fdi->sock = (read_fh[i])->fd; // FIXME: does not work under WIN32
881  ++fdi;
882  }
883  for (i = 0; i != write_fh_len; ++i)
884  {
885  fdi->fh = write_fh[i];
886  GNUNET_assert (NULL != fdi->fh);
888  fdi->sock = (write_fh[i])->fd; // FIXME: does not work under WIN32
889  ++fdi;
890  }
891  }
892 }
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
Information about an event relating to a file descriptor/socket.
int sock
Underlying OS handle the event was about.
enum GNUNET_SCHEDULER_EventType et
Type of the event that was generated related to sock.
int write_fd
Set if we only wait for writing to a single FD, otherwise -1.
Definition: scheduler.c:214
struct GNUNET_SCHEDULER_FdInfo fdx
Storage location used for fds if we want to avoid a separate malloc() call in the common case that th...
Definition: scheduler.c:167
int read_fd
Set if we only wait for reading from a single FD, otherwise -1.
Definition: scheduler.c:209

References GNUNET_SCHEDULER_FdInfo::et, GNUNET_SCHEDULER_FdInfo::fd, GNUNET_SCHEDULER_Task::fds, GNUNET_SCHEDULER_Task::fds_len, GNUNET_SCHEDULER_Task::fdx, GNUNET_SCHEDULER_FdInfo::fh, GNUNET_assert, GNUNET_NETWORK_get_fd(), GNUNET_new_array, GNUNET_SCHEDULER_ET_IN, GNUNET_SCHEDULER_ET_OUT, GNUNET_SCHEDULER_Task::read_fd, GNUNET_SCHEDULER_FdInfo::sock, t, and GNUNET_SCHEDULER_Task::write_fd.

Referenced by add_without_sets(), and GNUNET_SCHEDULER_add_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ driver_add_multiple()

static void driver_add_multiple ( struct GNUNET_SCHEDULER_Task t)
static

calls the given function func on each FdInfo related to t.

Optionally updates the event type field in each FdInfo after calling func.

Parameters
tthe task
driver_functhe function to call with each FdInfo contained in in t
if_not_readyonly call driver_func on FdInfos that are not ready
etthe event type to be set in each FdInfo after calling driver_func on it, or -1 if no updating not desired.

Definition at line 909 of file scheduler.c.

910 {
911  struct GNUNET_SCHEDULER_FdInfo *fdi;
912  int success = GNUNET_YES;
913 
914  for (unsigned int i = 0; i != t->fds_len; ++i)
915  {
916  fdi = &t->fds[i];
918  t,
919  fdi) && success;
921  }
922  if (GNUNET_YES != success)
923  {
925  "driver could not add task\n");
926  }
927 }
@ GNUNET_SCHEDULER_ET_NONE
No event (useful for timeout).
static const struct GNUNET_SCHEDULER_Driver * scheduler_driver
The driver used for the event loop.
Definition: scheduler.c:319
void * cls
Closure to pass to the functions in this struct.
int(* add)(void *cls, struct GNUNET_SCHEDULER_Task *task, struct GNUNET_SCHEDULER_FdInfo *fdi)
Add a task to be run if the conditions specified in the et field of the given fdi are satisfied.

References GNUNET_SCHEDULER_Driver::add, GNUNET_SCHEDULER_Driver::cls, GNUNET_SCHEDULER_FdInfo::et, GNUNET_SCHEDULER_Task::fds, GNUNET_SCHEDULER_Task::fds_len, GNUNET_ERROR_TYPE_ERROR, GNUNET_SCHEDULER_ET_NONE, GNUNET_YES, LOG, scheduler_driver, and t.

Referenced by add_without_sets(), and GNUNET_SCHEDULER_add_select().

Here is the caller graph for this function:

◆ install_parent_control_handler()

static void install_parent_control_handler ( void *  cls)
static

Definition at line 931 of file scheduler.c.

932 {
933  (void) cls;
936 }
void GNUNET_OS_install_parent_control_handler(void *cls)
Connects this process to its parent via pipe; essentially, the parent control handler will read signa...
Definition: os_priority.c:133
static struct GNUNET_SCHEDULER_Task * install_parent_control_task
Task for installing parent control handlers (it might happen that the scheduler is shutdown before th...
Definition: scheduler.c:387

References GNUNET_OS_install_parent_control_handler(), and install_parent_control_task.

Referenced by GNUNET_SCHEDULER_driver_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_pipe_cb()

static void shutdown_pipe_cb ( void *  cls)
static

Definition at line 940 of file scheduler.c.

941 {
942  char c;
943  const struct GNUNET_DISK_FileHandle *pr;
944 
945  (void) cls;
946  shutdown_pipe_task = NULL;
950  /* consume the signal */
951  GNUNET_DISK_file_read (pr, &c, sizeof(c));
952  /* mark all active tasks as ready due to shutdown */
956  pr,
958  NULL);
959 }
enum GNUNET_GenericReturnValue GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
Checks whether a handle is invalid.
Definition: disk.c:185
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:622
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1656
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static struct GNUNET_SCHEDULER_Task * shutdown_pipe_task
Task for reading from a pipe that signal handlers will use to initiate shutdown.
Definition: scheduler.c:393
static void shutdown_pipe_cb(void *cls)
Definition: scheduler.c:940

References GNUNET_assert, GNUNET_DISK_file_read(), GNUNET_DISK_handle_invalid(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_shutdown(), GNUNET_TIME_UNIT_FOREVER_REL, shutdown_pipe_handle, and shutdown_pipe_task.

Referenced by GNUNET_SCHEDULER_driver_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_backtrace()

static void init_backtrace ( struct GNUNET_SCHEDULER_Task t)
static

Initialize backtrace data for task t.

Parameters
ttask to initialize

Definition at line 1041 of file scheduler.c.

1042 {
1043 #if EXECINFO
1044  void *backtrace_array[MAX_TRACE_DEPTH];
1045 
1046  t->num_backtrace_strings
1047  = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1048  t->backtrace_strings =
1049  backtrace_symbols (backtrace_array,
1050  t->num_backtrace_strings);
1051  dump_backtrace (t);
1052 #else
1053  (void) t;
1054 #endif
1055 }

References dump_backtrace(), and t.

Referenced by add_without_sets(), GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_add_shutdown(), and GNUNET_SCHEDULER_add_with_reason_and_priority().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_without_sets()

static struct GNUNET_SCHEDULER_Task* add_without_sets ( struct GNUNET_TIME_Relative  delay,
enum GNUNET_SCHEDULER_Priority  priority,
const struct GNUNET_NETWORK_Handle read_nh,
const struct GNUNET_NETWORK_Handle write_nh,
const struct GNUNET_DISK_FileHandle read_fh,
const struct GNUNET_DISK_FileHandle write_fh,
GNUNET_SCHEDULER_TaskCallback  task,
void *  task_cls 
)
static

Schedule a new task to be run with a specified delay or when any of the specified file descriptor sets is ready.

The delay can be used as a timeout on the socket(s) being ready. The task will be scheduled for execution once either the delay has expired or any of the socket operations is ready. This is the most general function of the "add" family. Note that the "prerequisite_task" must be satisfied in addition to any of the other conditions. In other words, the task will be started when (prerequisite-run) && (delay-ready || any-rs-ready || any-ws-ready)

Parameters
delayhow long should we wait?
prioritypriority to use
rfdfile descriptor we want to read (can be -1)
wfdfile descriptors we want to write (can be -1)
taskmain function of the task
task_clsclosure of task
Returns
unique task identifier for the job only valid until task is started!

Definition at line 1434 of file scheduler.c.

1442 {
1443  struct GNUNET_SCHEDULER_Task *t;
1444 
1445  /* scheduler must be running */
1446  GNUNET_assert (NULL != scheduler_driver);
1447  GNUNET_assert (NULL != task);
1448  t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
1450  init_fd_info (t,
1451  &read_nh,
1452  read_nh ? 1 : 0,
1453  &write_nh,
1454  write_nh ? 1 : 0,
1455  &read_fh,
1456  read_fh ? 1 : 0,
1457  &write_fh,
1458  write_fh ? 1 : 0);
1459  t->callback = task;
1460  t->callback_cls = task_cls;
1461 #if DEBUG_FDS
1462  check_fd (t, NULL != read_nh ? GNUNET_NETWORK_get_fd (read_nh) : -1);
1463  check_fd (t, NULL != write_nh ? GNUNET_NETWORK_get_fd (write_nh) : -1);
1464  check_fd (t, NULL != read_fh ? read_fh->fd : -1);
1465  check_fd (t, NULL != write_fh ? write_fh->fd : -1);
1466 #endif
1467 #if PROFILE_DELAYS
1468  t->start_time = GNUNET_TIME_absolute_get ();
1469 #endif
1475  pending_tail,
1476  t);
1479  t->priority);
1480  init_backtrace (t);
1481  return t;
1482 }
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MAX(a, b)
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
@ GNUNET_SCHEDULER_PRIORITY_KEEP
Run with the same priority as the current job.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
static void driver_add_multiple(struct GNUNET_SCHEDULER_Task *t)
calls the given function func on each FdInfo related to t.
Definition: scheduler.c:909
static enum GNUNET_SCHEDULER_Priority current_priority
Priority of the task running right now.
Definition: scheduler.c:404
void init_fd_info(struct GNUNET_SCHEDULER_Task *t, const struct GNUNET_NETWORK_Handle *const *read_nh, unsigned int read_nh_len, const struct GNUNET_NETWORK_Handle *const *write_nh, unsigned int write_nh_len, const struct GNUNET_DISK_FileHandle *const *read_fh, unsigned int read_fh_len, const struct GNUNET_DISK_FileHandle *const *write_fh, unsigned int write_fh_len)
Definition: scheduler.c:791
static int current_lifeness
Value of the 'lifeness' flag for the current task.
Definition: scheduler.c:415
static void init_backtrace(struct GNUNET_SCHEDULER_Task *t)
Initialize backtrace data for task t.
Definition: scheduler.c:1041
static enum GNUNET_SCHEDULER_Priority max_priority_added
Priority of the highest task added in the current select iteration.
Definition: scheduler.c:410
static struct GNUNET_SCHEDULER_Task * pending_tail
Tail of list of tasks waiting for an event.
Definition: scheduler.c:329
void * callback_cls
Closure for the callback.
Definition: scheduler.c:155
struct GNUNET_AsyncScopeSave scope
Asynchronous scope of the task that scheduled this scope,.
Definition: scheduler.c:248
GNUNET_SCHEDULER_TaskCallback callback
Function to run when ready.
Definition: scheduler.c:150

References GNUNET_SCHEDULER_Task::callback, GNUNET_SCHEDULER_Task::callback_cls, check_priority(), current_lifeness, current_priority, delay, driver_add_multiple(), GNUNET_DISK_FileHandle::fd, GNUNET_assert, GNUNET_async_scope_get(), GNUNET_CONTAINER_DLL_insert, GNUNET_MAX, GNUNET_NETWORK_get_fd(), GNUNET_new, GNUNET_SCHEDULER_PRIORITY_KEEP, GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), init_backtrace(), init_fd_info(), GNUNET_SCHEDULER_Task::lifeness, max_priority_added, pending_head, pending_tail, GNUNET_SCHEDULER_Task::priority, scheduler_driver, GNUNET_SCHEDULER_Task::scope, t, and GNUNET_SCHEDULER_Task::timeout.

Referenced by GNUNET_SCHEDULER_add_file_with_priority(), and GNUNET_SCHEDULER_add_net_with_priority().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_handles()

void extract_handles ( const struct GNUNET_NETWORK_FDSet fdset,
const struct GNUNET_NETWORK_Handle ***  ntarget,
unsigned int *  extracted_nhandles,
const struct GNUNET_DISK_FileHandle ***  ftarget,
unsigned int *  extracted_fhandles 
)

Definition at line 1748 of file scheduler.c.

1753 {
1754  // FIXME: this implementation only works for unix, for WIN32 the file handles
1755  // in fdset must be handled separately
1756  const struct GNUNET_NETWORK_Handle **nhandles;
1757  const struct GNUNET_DISK_FileHandle **fhandles;
1758  unsigned int nhandles_len;
1759  unsigned int fhandles_len;
1760 
1761  nhandles = NULL;
1762  fhandles = NULL;
1763  nhandles_len = 0;
1764  fhandles_len = 0;
1765  for (int sock = 0; sock != fdset->nsds; ++sock)
1766  {
1767  if (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (fdset, sock))
1768  {
1769  struct GNUNET_NETWORK_Handle *nhandle;
1770  struct GNUNET_DISK_FileHandle *fhandle;
1771 
1772  nhandle = GNUNET_NETWORK_socket_box_native (sock);
1773  if (NULL != nhandle)
1774  {
1775  GNUNET_array_append (nhandles, nhandles_len, nhandle);
1776  }
1777  else
1778  {
1779  fhandle = GNUNET_DISK_get_handle_from_int_fd (sock);
1780  if (NULL != fhandle)
1781  {
1782  GNUNET_array_append (fhandles, fhandles_len, fhandle);
1783  }
1784  else
1785  {
1786  GNUNET_assert (0);
1787  }
1788  }
1789  }
1790  }
1791  *ntarget = nhandles_len > 0 ? nhandles : NULL;
1792  *ftarget = fhandles_len > 0 ? fhandles : NULL;
1793  *extracted_nhandles = nhandles_len;
1794  *extracted_fhandles = fhandles_len;
1795 }
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1330
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(int fd)
Box a native socket (and check that it is a socket).
Definition: network.c:579
int nsds
Maximum number of any socket descriptor in the set (plus one)

References GNUNET_array_append, GNUNET_assert, GNUNET_DISK_get_handle_from_int_fd(), GNUNET_NETWORK_fdset_test_native(), GNUNET_NETWORK_socket_box_native(), GNUNET_YES, and GNUNET_NETWORK_FDSet::nsds.

Referenced by GNUNET_SCHEDULER_add_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_add()

static int select_add ( void *  cls,
struct GNUNET_SCHEDULER_Task task,
struct GNUNET_SCHEDULER_FdInfo fdi 
)
static

Definition at line 2449 of file scheduler.c.

2452 {
2453  struct DriverContext *context = cls;
2454 
2455  GNUNET_assert (NULL != context);
2456  GNUNET_assert (NULL != task);
2457  GNUNET_assert (NULL != fdi);
2458  GNUNET_assert (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et) ||
2459  0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et));
2460 
2461  if (! ((NULL != fdi->fd) ^ (NULL != fdi->fh)) || (fdi->sock < 0))
2462  {
2463  /* exactly one out of {fd, hf} must be != NULL and the OS handle must be valid */
2464  return GNUNET_SYSERR;
2465  }
2466 
2467  struct Scheduled *scheduled = GNUNET_new (struct Scheduled);
2468  scheduled->task = task;
2469  scheduled->fdi = fdi;
2470  scheduled->et = fdi->et;
2471 
2472  GNUNET_CONTAINER_DLL_insert (context->scheduled_head,
2473  context->scheduled_tail,
2474  scheduled);
2475  return GNUNET_OK;
2476 }
Driver context used by GNUNET_SCHEDULER_run.
Definition: scheduler.c:291
enum GNUNET_SCHEDULER_EventType et
the event types (multiple event types can be ORed) the select driver is expected to wait for
Definition: scheduler.c:283
struct GNUNET_SCHEDULER_FdInfo * fdi
information about the network socket / file descriptor where the event is expected to occur
Definition: scheduler.c:277
struct GNUNET_SCHEDULER_Task * task
the task, the event is related to
Definition: scheduler.c:271

References context, GNUNET_SCHEDULER_FdInfo::et, Scheduled::et, GNUNET_SCHEDULER_FdInfo::fd, Scheduled::fdi, GNUNET_SCHEDULER_FdInfo::fh, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_ET_IN, GNUNET_SCHEDULER_ET_OUT, GNUNET_SYSERR, GNUNET_SCHEDULER_FdInfo::sock, and Scheduled::task.

Referenced by GNUNET_SCHEDULER_driver_select().

Here is the caller graph for this function:

◆ select_del()

static int select_del ( void *  cls,
struct GNUNET_SCHEDULER_Task task 
)
static

Definition at line 2480 of file scheduler.c.

2482 {
2483  struct DriverContext *context;
2484  struct Scheduled *pos;
2485  int ret;
2486 
2487  GNUNET_assert (NULL != cls);
2488 
2489  context = cls;
2490  ret = GNUNET_SYSERR;
2491  pos = context->scheduled_head;
2492  while (NULL != pos)
2493  {
2494  struct Scheduled *next = pos->next;
2495  if (pos->task == task)
2496  {
2497  GNUNET_CONTAINER_DLL_remove (context->scheduled_head,
2498  context->scheduled_tail,
2499  pos);
2500  GNUNET_free (pos);
2501  ret = GNUNET_OK;
2502  }
2503  pos = next;
2504  }
2505  return ret;
2506 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct Scheduled * next
Definition: scheduler.c:266

References context, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_OK, GNUNET_SYSERR, Scheduled::next, ret, and Scheduled::task.

Referenced by GNUNET_SCHEDULER_driver_select().

Here is the caller graph for this function:

◆ select_set_wakeup()

static void select_set_wakeup ( void *  cls,
struct GNUNET_TIME_Absolute  dt 
)
static

Definition at line 2510 of file scheduler.c.

2512 {
2513  struct DriverContext *context = cls;
2514 
2515  GNUNET_assert (NULL != context);
2516  context->timeout = dt;
2517 }

References context, and GNUNET_assert.

Referenced by GNUNET_SCHEDULER_driver_select().

Here is the caller graph for this function:

Variable Documentation

◆ pass_end_marker

struct GNUNET_SCHEDULER_Task pass_end_marker
static

Placed at the end of a ready queue to indicate where a scheduler run pass ends.

The next, prev, in_ready_list and priority fields are the only ones that should be used.

Definition at line 1 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_get_load(), remove_pass_end_marker(), and set_work_priority().

◆ scheduler_driver

◆ pending_head

◆ pending_tail

struct GNUNET_SCHEDULER_Task* pending_tail
static

Tail of list of tasks waiting for an event.

Definition at line 329 of file scheduler.c.

Referenced by add_without_sets(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_do_work(), and GNUNET_SCHEDULER_task_ready().

◆ shutdown_head

struct GNUNET_SCHEDULER_Task* shutdown_head
static

Head of list of tasks waiting for shutdown.

Definition at line 334 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_driver_done(), GNUNET_SCHEDULER_shutdown(), and shutdown_if_no_lifeness().

◆ shutdown_tail

struct GNUNET_SCHEDULER_Task* shutdown_tail
static

Tail of list of tasks waiting for shutdown.

Definition at line 339 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_cancel(), and GNUNET_SCHEDULER_shutdown().

◆ pending_timeout_head

struct GNUNET_SCHEDULER_Task* pending_timeout_head
static

List of tasks waiting ONLY for a timeout event.

Sorted by timeout (earliest first). Used so that we do not traverse the list of these tasks when building select sets (we just look at the head to determine the respective timeout ONCE).

Definition at line 348 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_driver_done(), and shutdown_if_no_lifeness().

◆ pending_timeout_tail

struct GNUNET_SCHEDULER_Task* pending_timeout_tail
static

List of tasks waiting ONLY for a timeout event.

Sorted by timeout (earliest first). Used so that we do not traverse the list of these tasks when building select sets (we just look at the head to determine the respective timeout ONCE).

Definition at line 357 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_cancel(), and GNUNET_SCHEDULER_do_work().

◆ pending_timeout_last

struct GNUNET_SCHEDULER_Task* pending_timeout_last
static

Last inserted task waiting ONLY for a timeout event.

Used to (heuristically) speed up insertion.

Definition at line 363 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_add_at_with_priority(), GNUNET_SCHEDULER_cancel(), and GNUNET_SCHEDULER_do_work().

◆ active_task

struct GNUNET_SCHEDULER_Task* active_task
static

ID of the task that is running right now.

Definition at line 368 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_begin_async_scope(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_get_load(), and GNUNET_SCHEDULER_get_task_context().

◆ ready_head

Head of list of tasks ready to run right now, grouped by importance.

Definition at line 374 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_driver_done(), GNUNET_SCHEDULER_get_load(), queue_ready_task(), remove_pass_end_marker(), and set_work_priority().

◆ ready_tail

Tail of list of tasks ready to run right now, grouped by importance.

Definition at line 380 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_do_work(), queue_ready_task(), remove_pass_end_marker(), and set_work_priority().

◆ install_parent_control_task

struct GNUNET_SCHEDULER_Task* install_parent_control_task
static

Task for installing parent control handlers (it might happen that the scheduler is shutdown before this task is executed, so GNUNET_SCHEDULER_shutdown must cancel it in that case)

Definition at line 387 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_driver_init(), GNUNET_SCHEDULER_shutdown(), and install_parent_control_handler().

◆ shutdown_pipe_task

struct GNUNET_SCHEDULER_Task* shutdown_pipe_task
static

Task for reading from a pipe that signal handlers will use to initiate shutdown.

Definition at line 393 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_driver_init(), GNUNET_SCHEDULER_shutdown(), and shutdown_pipe_cb().

◆ ready_count

unsigned int ready_count
static

◆ current_priority

enum GNUNET_SCHEDULER_Priority current_priority
static

Priority of the task running right now.

Only valid while a task is running.

Definition at line 398 of file scheduler.c.

Referenced by add_without_sets(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_driver_init(), and GNUNET_SCHEDULER_get_load().

◆ max_priority_added

enum GNUNET_SCHEDULER_Priority max_priority_added
static

Priority of the highest task added in the current select iteration.

Definition at line 398 of file scheduler.c.

Referenced by add_without_sets(), GNUNET_SCHEDULER_add_select(), and GNUNET_SCHEDULER_do_work().

◆ current_lifeness

◆ work_priority

enum GNUNET_SCHEDULER_Priority work_priority
static

◆ scheduler_select

GNUNET_SCHEDULER_select scheduler_select
static

Function to use as a select() in the scheduler.

If NULL, we use GNUNET_NETWORK_socket_select().

Definition at line 426 of file scheduler.c.

Referenced by check_priority(), and select_loop().

◆ tc

struct GNUNET_SCHEDULER_TaskContext tc
static

Task context of the current task.

Definition at line 426 of file scheduler.c.

Referenced by add_to_tc(), check_add_address(), check_add_queue_message(), check_client_send(), check_communicator_available(), check_incoming_msg(), client_connect_cb(), client_disconnect_cb(), client_send_response(), cmd_read(), connect_probe_continuation(), core_send_connect_info(), cores_send_connect_info(), cores_send_disconnect_info(), decrypt_and_check_tc(), do_blacklist_check(), do_read(), do_s5r_read(), do_udp_read(), finish_handling_raw_message(), free_address_list_entry(), free_pending_message(), free_queue(), gen_topo_2dtorus(), gen_topo_clique(), gen_topo_from_file(), gen_topo_line(), gen_topo_random(), gen_topo_ring(), gen_topo_scale_free(), gen_topo_star(), GNUNET_FS_share_tree_trim(), GNUNET_SCHEDULER_do_work(), GNUNET_SCHEDULER_get_task_context(), GNUNET_TESTBED_overlay_configure_topology_va(), GNUNET_TESTBED_underlay_construct_(), GST_blacklist_test_allowed(), GST_clients_broadcast(), GST_clients_broadcast_peer_notification(), handle_add_address(), handle_add_queue_message(), handle_backchannel_encapsulation(), handle_client_address_to_string(), handle_client_blacklist_init(), handle_client_blacklist_reply(), handle_client_hello(), handle_client_monitor_peers(), handle_client_monitor_plugins(), handle_client_recv_ok(), handle_client_send(), handle_client_set_metric(), handle_client_start(), handle_communicator_available(), handle_communicator_backchannel(), handle_del_address(), handle_del_queue_message(), handle_incoming_msg(), handle_monitor_start(), handle_queue_create_fail(), handle_queue_create_ok(), handle_request_hello_validation(), handle_send_message_ack(), handle_suggest(), handle_suggest_cancel(), handle_update_queue_message(), lookup_communicator(), maint_child_death(), make_link(), mark_match_down(), migrate_and_drop_keywords(), migrate_and_drop_metadata(), notify_client_about_neighbour(), notify_client_connect_info(), notify_client_queues(), notify_monitor(), notify_monitors(), oprelease_overlay_configure_topology(), opstart_overlay_configure_topology(), overlay_link_completed(), process_listen_socket(), proto_read_kx(), queue_read_kx(), read_dns4(), read_dns6(), read_response(), receive_ready(), remove_high_frequency_keywords(), share_tree_trim(), shutdown_task(), stop_peer_request(), suggest_to_connect(), tcp_send(), tokenized_cb(), transmit_kx(), transmit_ready(), udp_plugin_select_v4(), udp_plugin_select_v6(), unicast(), unix_plugin_select_read(), and unix_plugin_select_write().

◆ scheduler_select_cls

void* scheduler_select_cls
static

Closure for scheduler_select.

Definition at line 436 of file scheduler.c.

Referenced by check_priority(), and select_loop().

◆ shutdown_pipe_handle

struct GNUNET_DISK_PipeHandle* shutdown_pipe_handle
static

Pipe used to communicate shutdown via signal.

Definition at line 655 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_driver_done(), GNUNET_SCHEDULER_driver_init(), shutdown_pipe_cb(), and sighandler_shutdown().

◆ my_pid

pid_t my_pid
static

Process ID of this process at the time we installed the various signal handlers.

Definition at line 661 of file scheduler.c.

Referenced by GNUNET_SCHEDULER_driver_init(), and sighandler_shutdown().