silcschedule.h
- COPYRIGHT
-
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1998 - 2001 Pekka Riikonen
+ Copyright (C) 1998 - 2005 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
typedef enum {
/* File descriptor task that performs some event over file descriptors.
These tasks are for example network connections. */
- SILC_TASK_FD,
+ SILC_TASK_FD = 0,
/* Timeout tasks are tasks that are executed after the specified
time has elapsed. After the task is executed the task is removed
* The SILC_TASK_READ and SILC_TASK_WRITE may be set by the caller
* of the silc_schedule_set_listen_fd, if the caller needs to control
* the events for the task. The SILC_TASK_EXPIRE is set always only
- * by the scheduler when timeout expires for timeout task.
+ * by the scheduler when timeout expires for timeout task. The
+ * SILC_TASK_INTERRUPT is set for signal callback.
*
* SOURCE
*/
typedef enum {
- SILC_TASK_READ = 0x0001, /* Reading */
- SILC_TASK_WRITE = 0x0002, /* Writing */
- SILC_TASK_EXPIRE = 0x0004, /* Timeout */
+ SILC_TASK_READ = 0x0001, /* Reading */
+ SILC_TASK_WRITE = 0x0002, /* Writing */
+ SILC_TASK_EXPIRE = 0x0004, /* Timeout */
+ SILC_TASK_INTERRUPT = 0x0008, /* Signal */
} SilcTaskEvent;
/***/
has expired only and only when every other task with higher priority
has already been run. For non-timeout tasks this priority behaves
same way. Life is not fair for tasks with this priority. */
- SILC_TASK_PRI_LOW,
+ SILC_TASK_PRI_LOW = 0,
/* Normal priority that is used mostly in SILC. This is priority that
should always be used unless you specificly need some other priority.
*
* SYNOPSIS
*
- * typedef void (*SilcTaskCallback)(SilcSchedule schedule,
- * SilcTaskEvent type, SilcUInt32 fd,
+ * typedef void (*SilcTaskCallback)(SilcSchedule schedule,
+ * void *app_context,
+ * SilcTaskEvent type, SilcUInt32 fd,
* void *context);
*
* DESCRIPTION
* The `schedule' is the scheduler context, the `type' is the indicated
* event, the `fd' is the file descriptor of the task and the `context'
* is a caller specified context. If multiple events occurred this
- * callback is called separately for all events.
+ * callback is called separately for all events. The `app_context'
+ * is application specific context that was given as argument to the
+ * silc_schedule_init function.
*
* To specify task callback function in the application using the
* SILC_TASK_CALLBACK and SILC_TASK_CALLBACK_GLOBAL macros is
* recommended.
*
***/
-typedef void (*SilcTaskCallback)(SilcSchedule schedule, SilcTaskEvent type,
- SilcUInt32 fd, void *context);
+typedef void (*SilcTaskCallback)(SilcSchedule schedule, void *app_context,
+ SilcTaskEvent type, SilcUInt32 fd,
+ void *context);
/* Macros */
* SOURCE
*/
#define SILC_TASK_CALLBACK(func) \
-static void func(SilcSchedule schedule, SilcTaskEvent type, \
+static void func(SilcSchedule schedule, void *app_context, \
+ SilcTaskEvent type, \
SilcUInt32 fd, void *context)
/***/
*
* SOURCE
*/
-#define SILC_TASK_CALLBACK_GLOBAL(func) \
-void func(SilcSchedule schedule, SilcTaskEvent type, \
+#define SILC_TASK_CALLBACK_GLOBAL(func) \
+void func(SilcSchedule schedule, void *app_context, SilcTaskEvent type, \
SilcUInt32 fd, void *context)
/***/
*
* SYNOPSIS
*
- * SilcSchedule silc_schedule_init(int max_tasks);
+ * SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
*
* DESCRIPTION
*
* Initializes the scheduler. This returns the scheduler context that
* is given as argument usually to all silc_schedule_* functions.
* The `max_tasks' indicates the number of maximum tasks that the
- * scheduler can handle.
+ * scheduler can handle. The `app_context' is application specific
+ * context that is delivered to all task callbacks. The caller must
+ * free that context. The 'app_context' can be for example the
+ * application itself.
*
***/
-SilcSchedule silc_schedule_init(int max_tasks);
+SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
/****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
*
***/
void silc_schedule_wakeup(SilcSchedule schedule);
+/****f* silcutil/SilcScheduleAPI/silc_schedule_get_context
+ *
+ * SYNOPSIS
+ *
+ * void *silc_schedule_get_context(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ * Returns the application specific context that was saved into the
+ * scheduler in silc_schedule_init function. The context is also
+ * returned to application in task callback functions, but this function
+ * may be used to get it as well if needed.
+ *
+ ***/
+void *silc_schedule_get_context(SilcSchedule schedule);
+
/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add
*
* SYNOPSIS
* SYNOPSIS
*
* void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
- * SilcTaskEvent mask);
+ * SilcTaskEvent mask, bool send_events);
*
* DESCRIPTION
*
* 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.
+ *
***/
void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
- SilcTaskEvent mask);
+ SilcTaskEvent mask, bool send_events);
/****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
*
* SYNOPSIS
*
* void silc_schedule_signal_register(SilcSchedule schedule,
- * SilcUInt32 signal);
+ * SilcUInt32 signal,
+ * SilcTaskCallback callback,
+ * void *context);
*
* DESCRIPTION
*
* Register signal indicated by `signal' to the scheduler. Application
* should register all signals it is going to use to the scheduler.
- * To unregister a signal call silc_schedule_signal_unregister. On
- * platform that does not support signals calling this function has not
- * effect.
+ * The `callback' with `context' will be called after the application
+ * has called silc_schedule_signal_call function in the real signal
+ * callback. Application is responsible of calling that, and the
+ * signal system will not work without calling silc_schedule_signal_call
+ * function. The specified `signal' value will be also delivered to
+ * the `callback' as the fd-argument. The event type in the callback
+ * will be SILC_TASK_INTERRUPT. It is safe to use any SILC routines
+ * in the `callback' since it is actually called after the signal really
+ * happened.
+ *
+ * On platform that does not support signals calling this function has
+ * no effect.
+ *
+ * EXAMPLE
+ *
+ * Typical signal usage case on Unix systems:
+ *
+ * struct sigaction sa;
+ * sa.sa_handler = signal_handler;
+ * sigaction(SIGHUP, &sa, NULL);
+ * sigaction(SIGINT, &sa, NULL);
+ * silc_schedule_signal_register(schedule, SIGHUP, hup_signal, context);
+ * silc_schedule_signal_register(schedule, SIGINT, int_signal, context);
+ *
+ * static void signal_handler(int sig)
+ * {
+ * silc_schedule_signal_call(schedule, sig);
+ * }
+ *
+ * The `signal_handler' can be used as generic signal callback in the
+ * application that merely calls silc_schedule_signal_call, which then
+ * eventually will deliver for example the `hup_signal' callback. The
+ * same `signal_handler' can be used with all signals.
*
***/
-void silc_schedule_signal_register(SilcSchedule schedule, SilcUInt32 signal);
+void silc_schedule_signal_register(SilcSchedule schedule, SilcUInt32 signal,
+ SilcTaskCallback callback, void *context);
/****f* silcutil/SilcScheduleAPI/silc_schedule_signal_unregister
*
* SYNOPSIS
*
* void silc_schedule_signal_unregister(SilcSchedule schedule,
- * SilcUInt32 signal);
+ * SilcUInt32 signal,
+ * SilcTaskCallback callback,
+ * void *context);
*
* DESCRIPTION
*
* effect.
*
***/
-void silc_schedule_signal_unregister(SilcSchedule schedule, SilcUInt32 signal);
+void silc_schedule_signal_unregister(SilcSchedule schedule, SilcUInt32 signal,
+ SilcTaskCallback callback, void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_signal_call
+ *
+ * SYNOPSIS
+ *
+ * void silc_schedule_signal_call(SilcSchedule schedule,
+ * SilcUInt32 signal);
+ *
+ * DESCRIPTION
+ *
+ * Mark the `signal' to be called later. Every signal that has been
+ * registered by silc_schedule_signal_register is delivered by calling
+ * this function. When signal really occurs, the application is
+ * responsible of calling this function in the signal handler. After
+ * signal is over the scheduler will then safely deliver the callback
+ * that was given to silc_schedule_signal_register function.
+ *
+ ***/
+void silc_schedule_signal_call(SilcSchedule schedule, SilcUInt32 signal);
#endif