structure memory optimizations.
[silc.git] / lib / silcutil / silcschedule.h
index b0e315fda678cb64bd727b3c2348587ecd4e52bd..f10bd8306ad34e373993902c470732f122164ace 100644 (file)
@@ -20,7 +20,7 @@
 
 */
  
-/****h* silcutil/SilcScheduleAPI
+/****h* silcutil/SILC Schedule Interface
  *
  * DESCRIPTION
  *
@@ -119,8 +119,8 @@ typedef struct SilcTaskStruct *SilcTask;
 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
      automatically from the scheduler. It is safe to re-register the
@@ -157,14 +157,16 @@ typedef enum {
  *    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;
 /***/
 
@@ -188,7 +190,7 @@ typedef enum {
      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.
@@ -569,4 +571,93 @@ void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
  ***/
 void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
 
+/****f* silcutil/SilcScheduleAPI/silc_schedule_signal_register
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule_signal_register(SilcSchedule schedule, 
+ *                                       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.
+ *    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,
+                                  SilcTaskCallback callback, void *context);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_signal_unregister
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule_signal_unregister(SilcSchedule schedule, 
+ *                                         SilcUInt32 signal,
+ *                                        SilcTaskCallback callback,
+ *                                        void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Unregister a signal indicated by `signal' from the scheduler.  On
+ *    platform that does not support signals calling this function has no
+ *    effect.
+ *
+ ***/
+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