structure memory optimizations.
[silc.git] / lib / silcutil / silcschedule.h
index 1de2ec4c8e8deef4ecc8ed0f39e6a5ed5c6debdf..f10bd8306ad34e373993902c470732f122164ace 100644 (file)
@@ -119,7 +119,7 @@ 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
@@ -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.
@@ -574,25 +576,60 @@ void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 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
  *
@@ -601,6 +638,26 @@ void silc_schedule_signal_register(SilcSchedule schedule, SilcUInt32 signal);
  *    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