Symbian compilation fixes.
[crypto.git] / lib / silcutil / silcschedule.h
1 /*
2
3   silcschedule.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1998 - 2006 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
124   /* Platform specific process signal task.  On Unix systems this is one of
125      the signals described in signal(7).  On other platforms this may not
126      be available at all.  Only one callback per signal may be added. */
127   SILC_TASK_SIGNAL
128 } SilcTaskType;
129 /***/
130
131 /****d* silcutil/SilcScheduleAPI/SilcTaskEvent
132  *
133  * NAME
134  *
135  *    typedef enum { ... } SilcTaskEvent;
136  *
137  * DESCRIPTION
138  *
139  *    SILC Task event types.  The event type indicates the occurred
140  *    event of the task.  This type will be given as argument to the
141  *    SilcTaskCallback function to indicate the event for the caller.
142  *    The SILC_TASK_READ and SILC_TASK_WRITE may be set by the caller
143  *    of the silc_schedule_set_listen_fd, if the caller needs to control
144  *    the events for the task. The SILC_TASK_EXPIRE is set always only
145  *    by the scheduler when timeout expires for timeout task.  The
146  *    SILC_TASK_INTERRUPT is set for signal callback.
147  *
148  * SOURCE
149  */
150 typedef enum {
151   SILC_TASK_READ         = 0x0001,               /* Reading */
152   SILC_TASK_WRITE        = 0x0002,               /* Writing */
153   SILC_TASK_EXPIRE       = 0x0004,               /* Timeout */
154   SILC_TASK_INTERRUPT    = 0x0008,               /* Signal */
155 } SilcTaskEvent;
156 /***/
157
158 /****f* silcutil/SilcScheduleAPI/SilcTaskCallback
159  *
160  * SYNOPSIS
161  *
162  *    typedef void (*SilcTaskCallback)(SilcSchedule schedule,
163  *                                     void *app_context,
164  *                                     SilcTaskEvent type, SilcUInt32 fd,
165  *                                     void *context);
166  *
167  * DESCRIPTION
168  *
169  *    The task callback function.  This function will be called by the
170  *    scheduler when some event of the task is performed.  For example,
171  *    when data is available from the connection this will be called.
172  *
173  *    The `schedule' is the scheduler context, the `type' is the indicated
174  *    event, the `fd' is the file descriptor of the task and the `context'
175  *    is a caller specified context. If multiple events occurred this
176  *    callback is called separately for all events.  The `app_context'
177  *    is application specific context that was given as argument to the
178  *    silc_schedule_init function.  If the task is timeout task then `fd'
179  *    is zero (0).
180  *
181  *    To specify task callback function in the application using the
182  *    SILC_TASK_CALLBACK macro is recommended.
183  *
184  ***/
185 typedef void (*SilcTaskCallback)(SilcSchedule schedule, void *app_context,
186                                  SilcTaskEvent type, SilcUInt32 fd,
187                                  void *context);
188
189 /* Macros */
190
191 /****d* silcutil/SilcScheduleAPI/SILC_ALL_TASKS
192  *
193  * NAME
194  *
195  *    #define SILC_ALL_TASKS ...
196  *
197  * DESCRIPTION
198  *
199  *    Marks for all tasks in the scheduler. This can be passed to
200  *    silc_schedule_task_del function to delete all tasks at once.
201  *
202  * SOURCE
203  */
204 #define SILC_ALL_TASKS ((SilcTask)1)
205 /***/
206
207 /****d* silcutil/SilcScheduleAPI/SILC_TASK_CALLBACK
208  *
209  * NAME
210  *
211  *    #define SILC_TASK_CALLBACK ...
212  *
213  * DESCRIPTION
214  *
215  *    Generic macro to define task callback functions. This defines a
216  *    static function with name `func' as a task callback function.
217  *
218  * SOURCE
219  */
220 #define SILC_TASK_CALLBACK(func)                                        \
221 void func(SilcSchedule schedule, void *app_context, SilcTaskEvent type, \
222           SilcUInt32 fd, void *context)
223 /***/
224
225 /* Prototypes */
226
227 /****f* silcutil/SilcScheduleAPI/silc_schedule_init
228  *
229  * SYNOPSIS
230  *
231  *    SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
232  *
233  * DESCRIPTION
234  *
235  *    Initializes the scheduler. This returns the scheduler context that
236  *    is given as argument usually to all silc_schedule_* functions.
237  *    The `app_context' is application specific context that is delivered
238  *    to all task callbacks. The caller must free that context.  The
239  *    'app_context' can be for example the application itself.
240  *
241  *    The `max_tasks' is the maximum number of SILC_TASK_FD tasks in the
242  *    scheduler.  Set value to 0 to use default.  Operating system will
243  *    enforce the final limit.  On some operating systems the limit can
244  *    be significantly increased when this function is called in priviliged
245  *    mode (as super user).
246  *
247  ***/
248 SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
249
250 /****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
251  *
252  * SYNOPSIS
253  *
254  *    SilcBool silc_schedule_uninit(SilcSchedule schedule);
255  *
256  * DESCRIPTION
257  *
258  *    Uninitializes the scheduler. This is called when the program is ready
259  *    to end. This removes all tasks from the scheduler. Returns FALSE if the
260  *    scheduler could not be uninitialized. This happens when the scheduler
261  *    is still valid and silc_schedule_stop has not been called.
262  *
263  ***/
264 SilcBool silc_schedule_uninit(SilcSchedule schedule);
265
266 /****f* silcutil/SilcScheduleAPI/silc_schedule_stop
267  *
268  * SYNOPSIS
269  *
270  *    void silc_schedule_stop(SilcSchedule schedule);
271  *
272  * DESCRIPTION
273  *
274  *    Stops the scheduler even if it is not supposed to be stopped yet.
275  *    After calling this, one must call silc_schedule_uninit (after the
276  *    silc_schedule has returned).  After this is called it is guaranteed
277  *    that next time the scheduler enters the main loop it will be stopped.
278  *    However, untill it enters the main loop it will not detect that
279  *    it is stopped for example if this is called from another thread.
280  *
281  ***/
282 void silc_schedule_stop(SilcSchedule schedule);
283
284 /****f* silcutil/SilcScheduleAPI/silc_schedule
285  *
286  * SYNOPSIS
287  *
288  *    void silc_schedule(SilcSchedule schedule);
289  *
290  * DESCRIPTION
291  *
292  *    The SILC scheduler. The program will run inside this function.
293  *    When this returns the program is to be ended. Before this function can
294  *    be called, one must call silc_schedule_init function.
295  *
296  * NOTES
297  *
298  *    On Windows this will block the program, but will continue dispatching
299  *    window messages, and thus can be used as the main loop of the program.
300  *
301  *    On Symbian this will return immediately.  On Symbian calling
302  *    silc_schedule is same as calling silc_schedule_one.
303  *
304  ***/
305 void silc_schedule(SilcSchedule schedule);
306
307 /****f* silcutil/SilcScheduleAPI/silc_schedule_one
308  *
309  * SYNOPSIS
310  *
311  *    SilcBool silc_schedule_one(SilcSchedule schedule, int block);
312  *
313  * DESCRIPTION
314  *
315  *    Same as the silc_schedule but runs the scheduler only one round
316  *    and then returns.  This function is handy when the SILC scheduler
317  *    is used inside some other external scheduler, for example.  If
318  *    the `timeout_usecs' is non-negative a timeout will be added to the
319  *    scheduler.  The function will not return in this timeout unless
320  *    some other event occurs.
321  *
322  *    Typically this would be called from a timeout or idle task
323  *    periodically (typically from 5-50 ms) to schedule SILC tasks.  In
324  *    this case the `timeout_usecs' is usually 0.
325  *
326  ***/
327 SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs);
328
329 /****f* silcutil/SilcScheduleAPI/silc_schedule_wakeup
330  *
331  * SYNOPSIS
332  *
333  *    void silc_schedule_wakeup(SilcSchedule schedule);
334  *
335  * DESCRIPTION
336  *
337  *    Wakes up the scheduler. This is used only in multi-threaded
338  *    environments where threads may add new tasks or remove old tasks
339  *    from the scheduler. This is called to wake up the scheduler in the
340  *    main thread so that it detects the changes in the scheduler.
341  *    If threads support is not compiled in this function has no effect.
342  *    Implementation of this function may be platform specific.
343  *
344  ***/
345 void silc_schedule_wakeup(SilcSchedule schedule);
346
347 /****f* silcutil/SilcScheduleAPI/silc_schedule_get_context
348  *
349  * SYNOPSIS
350  *
351  *    void *silc_schedule_get_context(SilcSchedule schedule);
352  *
353  * DESCRIPTION
354  *
355  *    Returns the application specific context that was saved into the
356  *    scheduler in silc_schedule_init function.  The context is also
357  *    returned to application in task callback functions, but this function
358  *    may be used to get it as well if needed.
359  *
360  ***/
361 void *silc_schedule_get_context(SilcSchedule schedule);
362
363 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_fd
364  *
365  * SYNOPSIS
366  *
367  *    SilcTask
368  *    silc_schedule_task_add_fd(SilcSchedule schedule, SilcUInt32 fd,
369  *                              SilcTaskCallback callback, void *context);
370  *
371  * DESCRIPTION
372  *
373  *    Add file descriptor task to scheduler.  The `fd' may be either real
374  *    file descriptor, socket or on some platforms an opaque file descriptor
375  *    handle.  To receive events for the file descriptor set the correct
376  *    request events with silc_schedule_set_listen_fd function.
377  *
378  ***/
379 #define silc_schedule_task_add_fd(schedule, fd, callback, context)      \
380   silc_schedule_task_add(schedule, fd, callback, context, 0, 0, SILC_TASK_FD)
381
382 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_timeout
383  *
384  * SYNOPSIS
385  *
386  *    SilcTask
387  *    silc_schedule_task_add_timeout(SilcSchedule schedule,
388  *                                   SilcTaskCallback callback, void *context,
389  *                                   long seconds, long useconds);
390  *
391  * DESCRIPTION
392  *
393  *    Add timeout task to scheduler.  The `callback' will be called once
394  *    the specified timeout has elapsed.  The task will be removed from the
395  *    scheduler automatically once the task expires.  The event returned
396  *    to the `callback' is SILC_TASK_EXPIRE.  The task added with zero (0)
397  *    timeout will be executed immediately next time tasks are scheduled.
398  *
399  ***/
400 #define silc_schedule_task_add_timeout(schedule, callback, context, s, u) \
401   silc_schedule_task_add(schedule, 0, callback, context, s, u,          \
402                          SILC_TASK_TIMEOUT)
403
404 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_signal
405  *
406  * SYNOPSIS
407  *
408  *    SilcTask
409  *    silc_schedule_task_add_signal(SilcSchedule schedule, int signal,
410  *                                  SilcTaskCallback callback, void *context);
411  *
412  * DESCRIPTION
413  *
414  *    Add platform specific process signal handler to scheduler.  On Unix
415  *    systems the `signal' is one of the signal specified in signal(7).  On
416  *    other platforms this function may not be available at all, and has no
417  *    effect when called.  The event delivered to the `callback' is
418  *    SILC_TASK_INTERRUPT.
419  *
420  * NOTES
421  *
422  *    One signal may be registered only one callback.  Adding second callback
423  *    for signal that already has one will fail.
424  *
425  *    This function always returns NULL.  To remove signal from scheduler by
426  *    the signal call silc_schedule_task_del_by_fd.
427  *
428  ***/
429 #define silc_schedule_task_add_signal(schedule, sig, callback, context) \
430   silc_schedule_task_add(schedule, sig, callback, context, 0, 0,        \
431                          SILC_TASK_SIGNAL)
432
433 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del
434  *
435  * SYNOPSIS
436  *
437  *    void silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
438  *
439  * DESCRIPTION
440  *
441  *    Deletes the `task' from the scheduler indicated by the `schedule'.
442  *    After deleting the task it is guaranteed that the task callback
443  *    will not be called. If the `task' is SILC_ALL_TASKS then all
444  *    tasks is removed from the scheduler.
445  *
446  *    It is safe to call this function in any place. Tasks may be removed
447  *    in task callbacks (including in the task's own task callback) and
448  *    in multi-threaded environment in other threads as well.
449  *
450  ***/
451 void silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
452
453 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_fd
454  *
455  * SYNOPSIS
456  *
457  *    void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
458  *
459  * DESCRIPTION
460  *
461  *    Deletes a task from the scheduler by the specified `fd'.
462  *
463  *    It is safe to call this function in any place. Tasks may be removed
464  *    in task callbacks (including in the task's own task callback) and
465  *    in multi-threaded environment in other threads as well.
466  *
467  ***/
468 void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
469
470 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_callback
471  *
472  * SYNOPSIS
473  *
474  *    void silc_schedule_task_del_by_callback(SilcSchedule schedule,
475  *                                            SilcTaskCallback callback);
476  *
477  * DESCRIPTION
478  *
479  *    Deletes a task from the scheduler by the specified `callback' task
480  *    callback function.
481  *
482  *    It is safe to call this function in any place. Tasks may be removed
483  *    in task callbacks (including in the task's own task callback) and
484  *    in multi-threaded environment in other threads as well.
485  *
486  ***/
487 void silc_schedule_task_del_by_callback(SilcSchedule schedule,
488                                         SilcTaskCallback callback);
489
490 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_context
491  *
492  * SYNOPSIS
493  *
494  *    void silc_schedule_task_del_by_context(SilcSchedule schedule,
495  *                                           void *context);
496  *
497  * DESCRIPTION
498  *
499  *    Deletes a task from the scheduler by the specified `context'.
500  *
501  *    It is safe to call this function in any place. Tasks may be removed
502  *    in task callbacks (including in the task's own task callback) and
503  *    in multi-threaded environment in other threads as well.
504  *
505  ***/
506 void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context);
507
508 /****f* silcutil/SilcScheduleAPI/silc_schedule_task_del_by_all
509  *
510  * SYNOPSIS
511  *
512  *    void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
513  *                                       SilcTaskCallback callback,
514  *                                       void *context);
515  *
516  * DESCRIPTION
517  *
518  *    Deletes a task from the scheduler by the specified `fd', `callback'
519  *    and `context'.
520  *
521  *    It is safe to call this function in any place. Tasks may be removed
522  *    in task callbacks (including in the task's own task callback) and
523  *    in multi-threaded environment in other threads as well.
524  *
525  ***/
526 void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
527                                    SilcTaskCallback callback, void *context);
528
529 /****f* silcutil/SilcScheduleAPI/silc_schedule_set_listen_fd
530  *
531  * SYNOPSIS
532  *
533  *    void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
534  *                                     SilcTaskEvent mask,
535  *                                     SilcBool send_events);
536  *
537  * DESCRIPTION
538  *
539  *    Sets a file descriptor `fd' to be listened by the scheduler for
540  *    `mask' events.  To tell scheduler not to listen anymore for this
541  *    file descriptor call the silc_schedule_unset_listen_fd function.
542  *    When new task is created with silc_schedule_task_add the event
543  *    for the task's fd is initially set to SILC_TASK_READ. If you need
544  *    to control the task's fd's events you must call this function
545  *    whenever you need to change the events. This can be called multiple
546  *    times to change the events.
547  *
548  *    If the `send_events' is TRUE then this function sends the events
549  *    in `mask' to the application.  If FALSE then they are sent only
550  *    after the event occurs in reality.  In normal cases the `send_events'
551  *    is set to FALSE.
552  *
553  ***/
554 void silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
555                                  SilcTaskEvent mask, SilcBool send_events);
556
557 /****f* silcutil/SilcScheduleAPI/silc_schedule_get_fd_events
558  *
559  * SYNOPSIS
560  *
561  *    SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
562  *                                              SilcUInt32 fd);
563  *
564  * DESCRIPTION
565  *
566  *    Returns the file descriptor `fd' current requested events mask,
567  *    or 0 on error.
568  *
569  ***/
570 SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
571                                           SilcUInt32 fd);
572
573 /****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
574  *
575  * SYNOPSIS
576  *
577  *    void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
578  *
579  * DESCRIPTION
580  *
581  *    Tells the scheduler not to listen anymore for the specified
582  *    file descriptor `fd'. No events will be detected for the `fd'
583  *    after calling this function.
584  *
585  ***/
586 void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
587
588 #include "silcschedule_i.h"
589
590 #endif