Added SILC Server library.
[silc.git] / lib / silcutil / silcschedule.h
1 /*
2
3   silcschedule.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1998 - 2005 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/SILC Schedule Interface
21  *
22  * DESCRIPTION
23  *
24  * The SILC Scheduler is the heart of any application. The scheduler provides
25  * the application's main loop that can handle incoming data, outgoing data,
26  * timeouts and dispatch different kind of tasks.
27  *
28  * The SILC Scheduler supports file descriptor based tasks and timeout tasks.
29  * File descriptor tasks are tasks that perform some operation over the
30  * specified file descriptor. These include network connections, for example.
31  * The timeout tasks are timeouts that are executed after the specified
32  * timeout has elapsed.
33  *
34  * The SILC Scheduler is designed to be the sole main loop of the application
35  * so that the application does not need any other main loop.  However,
36  * SILC Scheduler does support running the scheduler only once, so that the
37  * scheduler does not block, and thus providing a possiblity that some
38  * external main loop is run over the SILC Scheduler.
39  *
40  * Typical application first initializes the scheduler and then registers
41  * the very first tasks to the scheduler and then run the scheduler.  After
42  * the scheduler's run function returns the application is considered to be
43  * ended.
44  *
45  * On WIN32 systems the SILC Scheduler is too designed to work as the main
46  * loop of the GUI application. It can handle all Windows messages and
47  * it dispatches them from the scheduler, and thus makes it possible to
48  * create GUI applications. The scheduler can also handle all kinds of
49  * WIN32 handles, this includes sockets created by the SILC Net API routines,
50  * WSAEVENT handle objects created by Winsock2 routines and arbitrary
51  * WIN32 HANDLE objects.
52  *
53  * The SILC Scheduler supports multi-threads as well. The actual scheduler
54  * must be run in single-thread but other threads may register new tasks
55  * and unregister old tasks.  However, it is enforced that the actual
56  * task is always run in the main thread.  The scheduler is context based
57  * which makes it possible to allocate several schedulers for one application.
58  * Since the scheduler must be run in single-thread, a multi-threaded
59  * application could be created by allocating own scheduler for each of the
60  * worker threads.
61  *
62  ***/
63
64 #ifndef SILCSCHEDULE_H
65 #define SILCSCHEDULE_H
66
67 /****s* silcutil/SilcScheduleAPI/SilcSchedule
68  *
69  * NAME
70  *
71  *    typedef struct SilcScheduleStruct *SilcSchedule;
72  *
73  * DESCRIPTION
74  *
75  *    This context is the actual Scheduler and is allocated by
76  *    the silc_schedule_init funtion.  The context is given as argument
77  *    to all silc_schedule_* functions.  It must be freed by the
78  *    silc_schedule_uninit function.
79  *
80  ***/
81 typedef struct SilcScheduleStruct *SilcSchedule;
82
83 /****s* silcutil/SilcScheduleAPI/SilcTask
84  *
85  * NAME
86  *
87  *    typedef struct SilcTaskStruct *SilcTask;
88  *
89  * DESCRIPTION
90  *
91  *    This object represents one task in the scheduler.  It is allocated
92  *    by the silc_schedule_task_add function and freed by one of the
93  *    silc_schedule_task_del* functions.
94  *
95  ***/
96 typedef struct SilcTaskStruct *SilcTask;
97
98 /****d* silcutil/SilcScheduleAPI/SilcTaskType
99  *
100  * NAME
101  *
102  *    typedef enum { ... } SilcTaskType;
103  *
104  * DESCRIPTION
105  *
106  *    SILC has two types of tasks, non-timeout tasks (tasks that perform
107  *    over file descriptors), and timeout tasks.  This type is sent as
108  *    argument for the task registering function, silc_schedule_task_add.
109  *
110  * SOURCE
111  */
112 typedef enum {
113   /* File descriptor task that performs some event over file descriptors.
114      These tasks are for example network connections. */
115   SILC_TASK_FD           = 0,
116
117   /* Timeout tasks are tasks that are executed after the specified
118      time has elapsed. After the task is executed the task is removed
119      automatically from the scheduler. It is safe to re-register the
120      task in task callback. It is also safe to unregister a task in
121      the task callback. */
122   SILC_TASK_TIMEOUT,
123 } SilcTaskType;
124 /***/
125
126 /****d* silcutil/SilcScheduleAPI/SilcTaskEvent
127  *
128  * NAME
129  *
130  *    typedef enum { ... } SilcTaskEvent;
131  *
132  * DESCRIPTION
133  *
134  *    SILC Task event types.  The event type indicates the occurred
135  *    event of the task.  This type will be given as argument to the
136  *    SilcTaskCallback function to indicate the event for the caller.
137  *    The SILC_TASK_READ and SILC_TASK_WRITE may be set by the caller
138  *    of the silc_schedule_set_listen_fd, if the caller needs to control
139  *    the events for the task. The SILC_TASK_EXPIRE is set always only
140  *    by the scheduler when timeout expires for timeout task.  The
141  *    SILC_TASK_INTERRUPT is set for signal callback.
142  *
143  * SOURCE
144  */
145 typedef enum {
146   SILC_TASK_READ         = 0x0001,               /* Reading */
147   SILC_TASK_WRITE        = 0x0002,               /* Writing */
148   SILC_TASK_EXPIRE       = 0x0004,               /* Timeout */
149   SILC_TASK_INTERRUPT    = 0x0008,               /* Signal */
150 } SilcTaskEvent;
151 /***/
152
153 /****f* silcutil/SilcScheduleAPI/SilcTaskCallback
154  *
155  * SYNOPSIS
156  *
157  *    typedef void (*SilcTaskCallback)(SilcSchedule schedule,
158  *                                     void *app_context,
159  *                                     SilcTaskEvent type, SilcUInt32 fd,
160  *                                     void *context);
161  *
162  * DESCRIPTION
163  *
164  *    The task callback function.  This function will be called by the
165  *    scheduler when some event of the task is performed.  For example,
166  *    when data is available from the connection this will be called.
167  *
168  *    The `schedule' is the scheduler context, the `type' is the indicated
169  *    event, the `fd' is the file descriptor of the task and the `context'
170  *    is a caller specified context. If multiple events occurred this
171  *    callback is called separately for all events.  The `app_context'
172  *    is application specific context that was given as argument to the
173  *    silc_schedule_init function.  If the task is timeout task then `fd'
174  *    is zero (0).
175  *
176  *    To specify task callback function in the application using the
177  *    SILC_TASK_CALLBACK macro is recommended.
178  *
179  ***/
180 typedef void (*SilcTaskCallback)(SilcSchedule schedule, void *app_context,
181                                  SilcTaskEvent type, SilcUInt32 fd,
182                                  void *context);
183
184 /* Macros */
185
186 /****d* silcutil/SilcScheduleAPI/SILC_ALL_TASKS
187  *
188  * NAME
189  *
190  *    #define SILC_ALL_TASKS ...
191  *
192  * DESCRIPTION
193  *
194  *    Marks for all tasks in the scheduler. This can be passed to
195  *    silc_schedule_task_del function to delete all tasks at once.
196  *
197  * SOURCE
198  */
199 #define SILC_ALL_TASKS ((SilcTask)1)
200 /***/
201
202 /****d* silcutil/SilcScheduleAPI/SILC_TASK_CALLBACK
203  *
204  * NAME
205  *
206  *    #define SILC_TASK_CALLBACK ...
207  *
208  * DESCRIPTION
209  *
210  *    Generic macro to define task callback functions. This defines a
211  *    static function with name `func' as a task callback function.
212  *
213  * SOURCE
214  */
215 #define SILC_TASK_CALLBACK(func)                                        \
216 void func(SilcSchedule schedule, void *app_context, SilcTaskEvent type, \
217           SilcUInt32 fd, void *context)
218 /***/
219
220 /* Prototypes */
221
222 /****f* silcutil/SilcScheduleAPI/silc_schedule_init
223  *
224  * SYNOPSIS
225  *
226  *    SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
227  *
228  * DESCRIPTION
229  *
230  *    Initializes the scheduler. This returns the scheduler context that
231  *    is given as argument usually to all silc_schedule_* functions.
232  *    The `app_context' is application specific context that is delivered
233  *    to all task callbacks. The caller must free that context.  The
234  *    'app_context' can be for example the application itself.
235  *
236  *    The `max_tasks' is the maximum number of SILC_TASK_FD tasks in the
237  *    scheduler.  Set value to 0 to use default.  Operating system will
238  *    enforce the final limit.  On some operating systems the limit can
239  *    be significantly increased when this function is called in priviliged
240  *    mode (as super user).
241  *
242  ***/
243 SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
244
245 /****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
246  *
247  * SYNOPSIS
248  *
249  *    SilcBool silc_schedule_uninit(SilcSchedule schedule);
250  *
251  * DESCRIPTION
252  *
253  *    Uninitializes the scheduler. This is called when the program is ready
254  *    to end. This removes all tasks from the scheduler. Returns FALSE if the
255  *    scheduler could not be uninitialized. This happens when the scheduler
256  *    is still valid and silc_schedule_stop has not been called.
257  *
258  ***/
259 SilcBool silc_schedule_uninit(SilcSchedule schedule);
260
261 /****f* silcutil/SilcScheduleAPI/silc_schedule_stop
262  *
263  * SYNOPSIS
264  *
265  *    void silc_schedule_stop(SilcSchedule schedule);
266  *
267  * DESCRIPTION
268  *
269  *    Stops the scheduler even if it is not supposed to be stopped yet.
270  *    After calling this, one must call silc_schedule_uninit (after the
271  *    silc_schedule has returned).  After this is called it is guaranteed
272  *    that next time the scheduler enters the main loop it will be stopped.
273  *    However, untill it enters the main loop it will not detect that
274  *    it is stopped for example if this is called from another thread.
275  *
276  ***/
277 void silc_schedule_stop(SilcSchedule schedule);
278
279 /****f* silcutil/SilcScheduleAPI/silc_schedule
280  *
281  * SYNOPSIS
282  *
283  *    void silc_schedule(SilcSchedule schedule);
284  *
285  * DESCRIPTION
286  *
287  *    The SILC scheduler. The program will run inside this function.
288  *    When this returns the program is to be ended. Before this function can
289  *    be called, one must call silc_schedule_init function.
290  *
291  ***/
292 void silc_schedule(SilcSchedule schedule);
293
294 /****f* silcutil/SilcScheduleAPI/silc_schedule_one
295  *
296  * SYNOPSIS
297  *
298  *    SilcBool silc_schedule_one(SilcSchedule schedule, int block);
299  *
300  * DESCRIPTION
301  *
302  *    Same as the silc_schedule but runs the scheduler only one round
303  *    and then returns.  This function is handy when the SILC scheduler
304  *    is used inside some other external scheduler, for example.  If
305  *    the `timeout_usecs' is non-negative a timeout will be added to the
306  *    scheduler.  The function will not return in this timeout unless
307  *    some other event occurs.
308  *
309  ***/
310 SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs);
311
312 /****f* silcutil/SilcScheduleAPI/silc_schedule_wakeup
313  *
314  * SYNOPSIS
315  *
316  *    void silc_schedule_wakeup(SilcSchedule schedule);
317  *
318  * DESCRIPTION
319  *
320  *    Wakes up the scheduler. This is used only in multi-threaded
321  *    environments where threads may add new tasks or remove old tasks
322  *    from the scheduler. This is called to wake up the scheduler in the
323  *    main thread so that it detects the changes in the scheduler.
324  *    If threads support is not compiled in this function has no effect.
325  *    Implementation of this function may be platform specific.
326  *
327  ***/
328 void silc_schedule_wakeup(SilcSchedule schedule);
329
330 /****f* silcutil/SilcScheduleAPI/silc_schedule_get_context
331  *
332  * SYNOPSIS
333  *
334  *    void *silc_schedule_get_context(SilcSchedule schedule);
335  *
336  * DESCRIPTION
337  *
338  *    Returns the application specific context that was saved into the
339  *    scheduler in silc_schedule_init function.  The context is also
340  *    returned to application in task callback functions, but this function
341  *    may be used to get it as well if needed.
342  *
343  ***/
344 void *silc_schedule_get_context(SilcSchedule schedule);
345
346 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add
347  *
348  * SYNOPSIS
349  *
350  *    SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
351  *                                    SilcTaskCallback callback,
352  *                                    void *context,
353  *                                    long seconds, long useconds,
354  *                                    SilcTaskType type);
355  *
356  * DESCRIPTION
357  *
358  *    Registers a new task to the scheduler. This same function is used
359  *    to register all types of tasks. The `type' argument tells what type
360  *    of the task is. Note that when registering non-timeout (fd) tasks one
361  *    should also pass 0 as timeout, as the timeout will be ignored anyway.
362  *    Also, note, that one cannot register timeout task with 0 timeout.
363  *    There cannot be zero timeouts, passing zero means no timeout is used
364  *    for the task and SILC_TASK_FD is used as default task type in
365  *    this case.
366  *
367  *    The `schedule' is the scheduler context. The `fd' is the file
368  *    descriptor of the task. On WIN32 systems the `fd' is not actual
369  *    file descriptor but some WIN32 event handle. On WIN32 system the `fd'
370  *    may be a socket created by the SILC Net API routines, WSAEVENT object
371  *    created by Winsock2 network routines or arbitrary WIN32 HANDLE object.
372  *    On Unix systems the `fd' is always the real file descriptor.  The
373  *    same `fd' can be added only once.
374  *
375  *    The `callback' is the task callback that will be called when some
376  *    event occurs for this task. The `context' is sent as argument to
377  *    the task `callback' function. For timeout tasks the callback is
378  *    called after the specified timeout has elapsed.
379  *
380  *    If the `type' is SILC_TASK_TIMEOUT then `seconds' and `useconds'
381  *    may be non-zero.  Otherwise they should be zero.
382  *
383  *    It is always safe to call this function in any place. New tasks
384  *    may be added also in task callbacks, and in multi-threaded environment
385  *    in other threads as well.
386  *
387  ***/
388 SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
389                                 SilcTaskCallback callback, void *context,
390                                 long seconds, long useconds,
391                                 SilcTaskType type);
392
393 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_fd
394  *
395  * SYNOPSIS
396  *
397  *    SilcTask
398  *    silc_schedule_task_add_fd(SilcSchedule schedule, SilcUInt32 fd,
399  *                              SilcTaskCallback callback, void *context);
400  *
401  * DESCRIPTION
402  *
403  *    A convenience function to add fd task.  You may use this if you
404  *    don't want to use the silc_schedule_task_add function to add fd task.
405  *
406  ***/
407 #define silc_schedule_task_add_fd(schedule, fd, callback, context)      \
408   silc_schedule_task_add(schedule, fd, callback, context, 0, 0, SILC_TASK_FD)
409
410 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_timeout
411  *
412  * SYNOPSIS
413  *
414  *    SilcTask
415  *    silc_schedule_task_add_timeout(SilcSchedule schedule,
416  *                                   SilcTaskCallback callback, void *context,
417  *                                   long seconds, long useconds);
418  *
419  * DESCRIPTION
420  *
421  *    A convenience function to add timeout task.  You may use this if
422  *    you don't want to use the silc_schedule_task_add function to add
423  *    timeout task.
424  *
425  ***/
426 #define silc_schedule_task_add_timeout(schedule, callback, context, s, u) \
427   silc_schedule_task_add(schedule, 0, callback, context, s, u,            \
428                          SILC_TASK_TIMEOUT)
429
430 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del
431  *
432  * SYNOPSIS
433  *
434  *    void silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
435  *
436  * DESCRIPTION
437  *
438  *    Deletes the `task' from the scheduler indicated by the `schedule'.
439  *    After deleting the task it is guaranteed that the task callback
440  *    will not be called. If the `task' is SILC_ALL_TASKS then all
441  *    tasks is removed from the scheduler.
442  *
443  *    It is safe to call this function in any place. Tasks may be removed
444  *    in task callbacks (including in the task's own task callback) and
445  *    in multi-threaded environment in other threads as well.
446  *
447  ***/
448 void silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
449
450 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_fd
451  *
452  * SYNOPSIS
453  *
454  *    void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
455  *
456  * DESCRIPTION
457  *
458  *    Deletes a task from the scheduler by the specified `fd'.
459  *
460  *    It is safe to call this function in any place. Tasks may be removed
461  *    in task callbacks (including in the task's own task callback) and
462  *    in multi-threaded environment in other threads as well.
463  *
464  ***/
465 void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
466
467 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_callback
468  *
469  * SYNOPSIS
470  *
471  *    void silc_schedule_task_del_by_callback(SilcSchedule schedule,
472  *                                            SilcTaskCallback callback);
473  *
474  * DESCRIPTION
475  *
476  *    Deletes a task from the scheduler by the specified `callback' task
477  *    callback function.
478  *
479  *    It is safe to call this function in any place. Tasks may be removed
480  *    in task callbacks (including in the task's own task callback) and
481  *    in multi-threaded environment in other threads as well.
482  *
483  ***/
484 void silc_schedule_task_del_by_callback(SilcSchedule schedule,
485                                         SilcTaskCallback callback);
486
487 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_context
488  *
489  * SYNOPSIS
490  *
491  *    void silc_schedule_task_del_by_context(SilcSchedule schedule,
492  *                                           void *context);
493  *
494  * DESCRIPTION
495  *
496  *    Deletes a task from the scheduler by the specified `context'.
497  *
498  *    It is safe to call this function in any place. Tasks may be removed
499  *    in task callbacks (including in the task's own task callback) and
500  *    in multi-threaded environment in other threads as well.
501  *
502  ***/
503 void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context);
504
505 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_all
506  *
507  * SYNOPSIS
508  *
509  *    void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
510  *                                       SilcTaskCallback callback,
511  *                                       void *context);
512  *
513  * DESCRIPTION
514  *
515  *    Deletes a task from the scheduler by the specified `fd', `callback'
516  *    and `context'.
517  *
518  *    It is safe to call this function in any place. Tasks may be removed
519  *    in task callbacks (including in the task's own task callback) and
520  *    in multi-threaded environment in other threads as well.
521  *
522  ***/
523 void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
524                                    SilcTaskCallback callback, void *context);
525
526 /****f* silcutil/SilcScheduleAPI/silc_schedule_set_listen_fd
527  *
528  * SYNOPSIS
529  *
530  *    void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
531  *                                     SilcTaskEvent mask, SilcBool send_events);
532  *
533  * DESCRIPTION
534  *
535  *    Sets a file descriptor `fd' to be listened by the scheduler for
536  *    `mask' events.  To tell scheduler not to listen anymore for this
537  *    file descriptor call the silc_schedule_unset_listen_fd function.
538  *    When new task is created with silc_schedule_task_add the event
539  *    for the task's fd is initially set to SILC_TASK_READ. If you need
540  *    to control the task's fd's events you must call this function
541  *    whenever you need to change the events. This can be called multiple
542  *    times to change the events.
543  *
544  *    If the `send_events' is TRUE then this function sends the events
545  *    in `mask' to the application.  If FALSE then they are sent only
546  *    after the event occurs in reality.  In normal cases the `send_events'
547  *    is set to FALSE.
548  *
549  ***/
550 void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
551                                  SilcTaskEvent mask, SilcBool send_events);
552
553 /****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
554  *
555  * SYNOPSIS
556  *
557  *    void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
558  *
559  * DESCRIPTION
560  *
561  *    Tells the scheduler not to listen anymore for the specified
562  *    file descriptor `fd'. No events will be detected for the `fd'
563  *    after calling this function.
564  *
565  ***/
566 void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
567
568 /****f* silcutil/SilcScheduleAPI/silc_schedule_signal_register
569  *
570  * SYNOPSIS
571  *
572  *    void silc_schedule_signal_register(SilcSchedule schedule,
573  *                                       SilcUInt32 signal,
574  *                                       SilcTaskCallback callback,
575  *                                       void *context);
576  *
577  * DESCRIPTION
578  *
579  *    Register signal indicated by `signal' to the scheduler.  Application
580  *    should register all signals it is going to use to the scheduler.
581  *    The `callback' with `context' will be called after the application
582  *    has called silc_schedule_signal_call function in the real signal
583  *    callback.  Application is responsible of calling that, and the
584  *    signal system will not work without calling silc_schedule_signal_call
585  *    function.  The specified `signal' value will be also delivered to
586  *    the `callback' as the fd-argument.  The event type in the callback
587  *    will be SILC_TASK_INTERRUPT.  It is safe to use any SILC routines
588  *    in the `callback' since it is actually called after the signal really
589  *    happened.
590  *
591  *    On platform that does not support signals calling this function has
592  *    no effect.
593  *
594  * EXAMPLE
595  *
596  *    Typical signal usage case on Unix systems:
597  *
598  *    struct sigaction sa;
599  *    sa.sa_handler = signal_handler;
600  *    sigaction(SIGHUP, &sa, NULL);
601  *    sigaction(SIGINT, &sa, NULL);
602  *    silc_schedule_signal_register(schedule, SIGHUP, hup_signal, context);
603  *    silc_schedule_signal_register(schedule, SIGINT, int_signal, context);
604  *
605  *    static void signal_handler(int sig)
606  *    {
607  *      silc_schedule_signal_call(schedule, sig);
608  *    }
609  *
610  *    The `signal_handler' can be used as generic signal callback in the
611  *    application that merely calls silc_schedule_signal_call, which then
612  *    eventually will deliver for example the `hup_signal' callback.  The
613  *    same `signal_handler' can be used with all signals.
614  *
615  ***/
616 void silc_schedule_signal_register(SilcSchedule schedule, SilcUInt32 signal,
617                                    SilcTaskCallback callback, void *context);
618
619 /****f* silcutil/SilcScheduleAPI/silc_schedule_signal_unregister
620  *
621  * SYNOPSIS
622  *
623  *    void silc_schedule_signal_unregister(SilcSchedule schedule,
624  *                                         SilcUInt32 signal,
625  *                                         SilcTaskCallback callback,
626  *                                         void *context);
627  *
628  * DESCRIPTION
629  *
630  *    Unregister a signal indicated by `signal' from the scheduler.  On
631  *    platform that does not support signals calling this function has no
632  *    effect.
633  *
634  ***/
635 void silc_schedule_signal_unregister(SilcSchedule schedule, SilcUInt32 signal,
636                                      SilcTaskCallback callback, void *context);
637
638 /****f* silcutil/SilcScheduleAPI/silc_schedule_signal_call
639  *
640  * SYNOPSIS
641  *
642  *    void silc_schedule_signal_call(SilcSchedule schedule,
643  *                                   SilcUInt32 signal);
644  *
645  * DESCRIPTION
646  *
647  *    Mark the `signal' to be called later.  Every signal that has been
648  *    registered by silc_schedule_signal_register is delivered by calling
649  *    this function.  When signal really occurs, the application is
650  *    responsible of calling this function in the signal handler.  After
651  *    signal is over the scheduler will then safely deliver the callback
652  *    that was given to silc_schedule_signal_register function.
653  *
654  ***/
655 void silc_schedule_signal_call(SilcSchedule schedule, SilcUInt32 signal);
656
657 #include "silcschedule_i.h"
658
659 #endif