+/****f* silcutil/SilcScheduleAPI/silc_schedule_get_global
+ *
+ * SYNOPSIS
+ *
+ * SilcSchedule silc_schedule_get_global(void);
+ *
+ * DESCRIPTION
+ *
+ * Returns the thread's global scheduler that was set by calling
+ * silc_schedule_set_global or NULL if global scheduler has not been set.
+ *
+ ***/
+SilcSchedule silc_schedule_get_global(void);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_fd
+ *
+ * SYNOPSIS
+ *
+ * SilcTask
+ * silc_schedule_task_add_fd(SilcSchedule schedule, SilcUInt32 fd,
+ * SilcTaskCallback callback, void *context);
+ *
+ * DESCRIPTION
+ *
+ * Add file descriptor task to scheduler. The `fd' may be either real
+ * file descriptor, socket or on some platforms an opaque file descriptor
+ * handle. To receive events for the file descriptor set the correct
+ * request events with silc_schedule_set_listen_fd function.
+ *
+ * The task will be initially set for SILC_TASK_READ events. Setting that
+ * event immediately after this call returns is not necessary.
+ *
+ * This returns the new task or NULL on error. If a task with `fd' has
+ * already been added this will return the existing task pointer.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+#define silc_schedule_task_add_fd(schedule, fd, callback, context) \
+ silc_schedule_task_add(schedule, fd, callback, context, 0, 0, SILC_TASK_FD)
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_timeout
+ *
+ * SYNOPSIS
+ *
+ * SilcTask
+ * silc_schedule_task_add_timeout(SilcSchedule schedule,
+ * SilcTaskCallback callback, void *context,
+ * long seconds, long useconds);
+ *
+ * DESCRIPTION
+ *
+ * Add timeout task to scheduler. The `callback' will be called once
+ * the specified timeout has elapsed. The task will be removed from the
+ * scheduler automatically once the task expires. The event returned
+ * to the `callback' is SILC_TASK_EXPIRE. A task added with zero (0)
+ * timeout will be executed immediately next time tasks are scheduled.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+#define silc_schedule_task_add_timeout(schedule, callback, context, s, u) \
+ silc_schedule_task_add(schedule, 0, callback, context, s, u, \
+ SILC_TASK_TIMEOUT)
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_signal
+ *
+ * SYNOPSIS
+ *
+ * SilcTask
+ * silc_schedule_task_add_signal(SilcSchedule schedule, int signal,
+ * SilcTaskCallback callback, void *context);
+ *
+ * DESCRIPTION
+ *
+ * Add platform specific process signal handler to scheduler. On Unix
+ * systems the `signal' is one of the signal specified in signal(7). On
+ * other platforms this function may not be available at all, and has no
+ * effect when called. The event delivered to the `callback' is
+ * SILC_TASK_INTERRUPT.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ * NOTES
+ *
+ * One signal may be registered only one callback. Adding second callback
+ * for signal that already has one will fail.
+ *
+ * This function always returns NULL. To remove signal from scheduler by
+ * the signal call silc_schedule_task_del_by_fd.
+ *
+ ***/
+#define silc_schedule_task_add_signal(schedule, sig, callback, context) \
+ silc_schedule_task_add(schedule, sig, callback, context, 0, 0, \
+ SILC_TASK_SIGNAL)
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_event
+ *
+ * SYNOPSIS
+ *
+ * SilcTask
+ * silc_schedule_task_add_event(SilcSchedule schedule,
+ * const char *event, ...);
+ *
+ * DESCRIPTION
+ *
+ * Adds an event task to scheduler. These tasks are asynchronous events
+ * that one or more receivers may connect to and receive information or
+ * data when the event is signalled. Event tasks are fast and may be
+ * used to efficiently deliver events and data to multiple receivers. The
+ * `event' is the name of the event, and can be used to connect to the
+ * event and to signal it.
+ *
+ * The events are global among the `scheduler', its parent scheduler and
+ * any of its child schedulers. It does not matter to which scheduler
+ * event is added to, connected to or signalled. Signal will reach any
+ * connected entity, as long as it is the parent or one of the fellow
+ * children of `schedule'.
+ *
+ * To connect to an event call silc_schedule_event_connect.
+ * To disconnect from event call silc_schedule_event_disconnect.
+ * To signal event call silc_schedule_event_signal.
+ * To delete event task call silc_schedule_task_del or
+ * silc_schedule_task_del_event.
+ *
+ * The variable argument list is used to describe the arguments of the
+ * event. The variable arguments are a list of zero or more SilcParam
+ * values. This function returns the event task context or NULL on error.
+ *
+ * EXAMPLE
+ *
+ * // Register 'connected' event
+ * silc_schedule_task_add_event(schedule, "connected",
+ * SILC_PARAM_UINT32,
+ * SILC_PARAM_BUFFER);
+ *
+ * // Connect to 'connected' event
+ * silc_schedule_event_connect(schedule, "connected", NULL,
+ * connected_cb, ctx);
+ *
+ * // Signal 'connected' event
+ * silc_schedule_event_signal(schedule, "connected", NULL, integer, buf);
+ *
+ * // 'connected' event handler
+ * SILC_TASK_CALLBACK(connected_cb)
+ * {
+ * FooCtx ctx = context;
+ * SilcUInt32 integer;
+ * SilcBuffer buf;
+ *
+ * integer = va_arg(va, SilcUInt32);
+ * buf = va_arg(va, SilcBuffer);
+ * ...
+ * }
+ *
+ ***/
+SilcTask silc_schedule_task_add_event(SilcSchedule schedule,
+ const char *event, ...);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
+ *
+ * DESCRIPTION
+ *
+ * Deletes the `task' from the scheduler indicated by the `schedule'.
+ * After deleting the task it is guaranteed that the task callback
+ * will not be called. If the `task' is SILC_ALL_TASKS then all
+ * tasks is removed from the scheduler. Returns always TRUE.
+ *
+ * It is safe to call this function in any place. Tasks may be removed
+ * in task callbacks (including in the task's own task callback) and
+ * in multi-threaded environment in other threads as well.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_fd
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_task_del_by_fd(SilcSchedule schedule,
+ * SilcUInt32 fd);
+ *
+ * DESCRIPTION
+ *
+ * Deletes a task from the scheduler by the specified `fd'. Returns
+ * FALSE if such fd task does not exist.
+ *
+ * It is safe to call this function in any place. Tasks may be removed
+ * in task callbacks (including in the task's own task callback) and
+ * in multi-threaded environment in other threads as well.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_callback
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule,
+ * SilcTaskCallback callback);
+ *
+ * DESCRIPTION
+ *
+ * Deletes a task from the scheduler by the specified `callback' task
+ * callback function. Returns FALSE if such task with such callback
+ * does not exist.
+ *
+ * It is safe to call this function in any place. Tasks may be removed
+ * in task callbacks (including in the task's own task callback) and
+ * in multi-threaded environment in other threads as well.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule,
+ SilcTaskCallback callback);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_context
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Deletes a task from the scheduler by the specified `context'. Returns
+ * FALSE if such task with such context does not exist.
+ *
+ * It is safe to call this function in any place. Tasks may be removed
+ * in task callbacks (including in the task's own task callback) and
+ * in multi-threaded environment in other threads as well.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule,
+ void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_all
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
+ * SilcTaskCallback callback,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Deletes a task from the scheduler by the specified `fd', `callback'
+ * and `context'. Returns FALSE if such task does not exist.
+ *
+ * It is safe to call this function in any place. Tasks may be removed
+ * in task callbacks (including in the task's own task callback) and
+ * in multi-threaded environment in other threads as well.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
+ SilcTaskCallback callback,
+ void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_event
+ *
+ * SYNOPSIS
+ *
+ * void silc_schedule_task_del_event(SilcSchedule schedule,
+ * const char *event);
+ *
+ * DESCRIPTION
+ *
+ * Deletes event task by the event name `event'. Returns FALSE if the
+ * event does not exist. Events can be deleted by calling the
+ * silc_schedule_task_del also.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcBool silc_schedule_task_del_event(SilcSchedule schedule,
+ const char *event);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_set_listen_fd
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_set_listen_fd(SilcSchedule schedule,
+ * SilcUInt32 fd,
+ * SilcTaskEvent mask,
+ * SilcBool send_events);
+ *
+ * DESCRIPTION
+ *
+ * Sets a file descriptor `fd' to be listened by the scheduler for
+ * `mask' events. To tell scheduler not to listen anymore for this
+ * file descriptor call the silc_schedule_unset_listen_fd function.
+ * When new task is created with silc_schedule_task_add the event
+ * for the task's fd is initially set to SILC_TASK_READ. If you need
+ * to control the task's fd's events you must call this function
+ * whenever you need to change the events. This can be called multiple
+ * times to change the events.
+ *
+ * If the `send_events' is TRUE then this function sends the events
+ * in `mask' to the application. If FALSE then they are sent only
+ * after the event occurs in reality. In normal cases the `send_events'
+ * is set to FALSE.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ * Returns FALSE if the operation could not performed and TRUE if it
+ * was a success.
+ *
+ ***/
+SilcBool silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
+ SilcTaskEvent mask, SilcBool send_events);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_get_fd_events
+ *
+ * SYNOPSIS
+ *
+ * SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
+ * SilcUInt32 fd);
+ *
+ * DESCRIPTION
+ *
+ * Returns the file descriptor `fd' current requested events mask,
+ * or 0 on error.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
+ SilcUInt32 fd);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
+ *
+ * SYNOPSIS
+ *
+ * void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
+ *
+ * DESCRIPTION
+ *
+ * Tells the scheduler not to listen anymore for the specified
+ * file descriptor `fd'. No events will be detected for the `fd'
+ * after calling this function.
+ *
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
+ ***/
+void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_event_connect
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_event_connect(SilcSchedule schedule,
+ * const char *event, SilcTask task,
+ * SilcTaskEventCallback callback,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Connects to an event task. The `event' or `task' must be non-NULL.
+ * If `event' is non-NULL it is the name of the event to connect to. If
+ * the `task' is non-NULL it is the event task to connect to. The event
+ * SilcTask pointer is returned by silc_schedule_task_add_event when the
+ * even is added to scheduler.
+ *
+ * The `callback' with `context' and with `schedule' are called when the
+ * even task is signalled with silc_schedule_event_signal.
+ *
+ * Returns FALSE on error or if the `callback' with `context' has already
+ * been connected. Otherwise, returns TRUE.
+ *
+ * EXAMPLE
+ *
+ * silc_schedule_event_connect(schedule, "foo event", NULL,
+ * foo_signal_callback, foo_context);
+ *
+ ***/
+SilcBool silc_schedule_event_connect(SilcSchedule schedule,
+ const char *event, SilcTask task,
+ SilcTaskEventCallback callback,
+ void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_event_disconnect
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_event_disconnect(SilcSchedule schedule,
+ * const char *event, SilcTask task,
+ * SilcTaskEventCallback callback,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Disconnects the `callback' and `context' from an event task. The `event'
+ * or `task' must be non-NULL. If `event' is non-NULL it is the name of
+ * the event. If `task' is non-NULL it is the event task.
+ *
+ * Returns FALSE on error or if the `callback' with `context' has not been
+ * connected. Otherwise, returns TRUE.
+ *
+ * EXAMPLE
+ *
+ * silc_schedule_event_connect(schedule, "foo event", NULL,
+ * foo_signal_callback, foo_context);
+ *
+ ***/
+SilcBool silc_schedule_event_disconnect(SilcSchedule schedule,
+ const char *event, SilcTask task,
+ SilcTaskEventCallback callback,
+ void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_event_signal
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_schedule_event_signal(SilcSchedule schedule,
+ * const char *event,
+ * SilcTask task, ...);
+ *
+ * DESCRIPTION
+ *
+ * Signals an event task. The `event' or `task' must be non-NULL. If
+ * `event' is non-NULL it is the name of the event to signal. If the `task'
+ * is non-NULL it is the task to be signalled. It is marginally faster
+ * to use the `task' pointer directly instead of `event' to send the signal.
+ *
+ * The variable arguments are the arguments to be sent in the signal to
+ * the connected entities. The silc_schedule_task_add_event defines what
+ * arguments must be sent to each signal.
+ *
+ * Signal delivery is synchronous; the signal is delivered inside this
+ * function. If a receiver was originally in another thread, the signal
+ * is delivered in the thread where this function is called. This means
+ * that concurrency control (locking) is required if the application uses
+ * events in multiple threads.
+ *
+ * EXAMPLE
+ *
+ * silc_schedule_event_signal(schedule, "foo event", NULL, intarg, buffer);
+ *
+ ***/
+SilcBool silc_schedule_event_signal(SilcSchedule schedule, const char *event,
+ SilcTask task, ...);