Internal scheduler initialization cannot return NULL anymore.
[crypto.git] / lib / silcutil / silcschedule_i.h
1 /*
2
3   silcschedule_i.h.
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2001 - 2007 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 #ifndef SILCSCHEDULE_I_H
21 #define SILCSCHEDULE_I_H
22
23 #ifndef SILCSCHEDULE_H
24 #error "Do not include this header directly"
25 #endif
26
27 #include "silchashtable.h"
28 #include "silclist.h"
29
30 /* Task header */
31 struct SilcTaskStruct {
32   struct SilcTaskStruct *next;
33   SilcTaskCallback callback;
34   void *context;
35   unsigned int type    : 1;     /* 0 = fd, 1 = timeout */
36   unsigned int valid   : 1;     /* Set if task is valid */
37 };
38
39 /* Timeout task */
40 typedef struct SilcTaskTimeoutStruct {
41   struct SilcTaskStruct header;
42   struct timeval timeout;
43 } *SilcTaskTimeout;
44
45 /* Fd task */
46 typedef struct SilcTaskFdStruct {
47   struct SilcTaskStruct header;
48   unsigned int scheduled  : 1;
49   unsigned int events     : 14;
50   unsigned int revents    : 15;
51   SilcUInt32 fd;
52 } *SilcTaskFd;
53
54 /* Scheduler context */
55 struct SilcScheduleStruct {
56   void *internal;
57   void *app_context;               /* Application specific context */
58   SilcHashTable fd_queue;          /* FD task queue */
59   SilcList fd_dispatch;            /* Dispatched FDs */
60   SilcList timeout_queue;          /* Timeout queue */
61   SilcList free_tasks;             /* Timeout task freelist */
62   SilcMutex lock;                  /* Scheduler lock */
63   struct timeval timeout;          /* Current timeout */
64   unsigned int max_tasks     : 29; /* Max FD tasks */
65   unsigned int has_timeout   : 1;  /* Set if timeout is set */
66   unsigned int valid         : 1;  /* Set if scheduler is valid */
67   unsigned int signal_tasks  : 1;  /* Set if to dispatch signals */
68 };
69
70 /* Locks. These also blocks signals that we care about and thus guarantee
71    that while we are in scheduler no signals can happen.  This way we can
72    synchronise signals with SILC Scheduler. */
73 #define SILC_SCHEDULE_LOCK(schedule)                            \
74 do {                                                            \
75   silc_mutex_lock(schedule->lock);                              \
76   schedule_ops.signals_block(schedule, schedule->internal);     \
77 } while (0)
78 #define SILC_SCHEDULE_UNLOCK(schedule)                          \
79 do {                                                            \
80   schedule_ops.signals_unblock(schedule, schedule->internal);   \
81   silc_mutex_unlock(schedule->lock);                            \
82 } while (0)
83
84 /* Platform specific scheduler operations */
85 typedef struct {
86   /* Initializes the platform specific scheduler.  This for example initializes
87      the wakeup mechanism of the scheduler.  In multi-threaded environment
88      the scheduler needs to be wakenup when tasks are added or removed from
89      the task queues.  Returns context to the platform specific scheduler.
90      If this returns NULL the scheduler initialization will fail. */
91   void *(*init)(SilcSchedule schedule, void *app_context);
92
93   /* Uninitializes the platform specific scheduler context. */
94   void (*uninit)(SilcSchedule schedule, void *context);
95
96   /* System specific waiter. This must fill the schedule->fd_dispatch queue
97      with valid tasks that has something to dispatch, when this returns. */
98   int (*schedule)(SilcSchedule schedule, void *context);
99
100   /* Schedule `task' with events `event_mask'. Zero `event_mask'
101      unschedules the task. */
102   SilcBool (*schedule_fd)(SilcSchedule schedule, void *context,
103                           SilcTaskFd task, SilcTaskEvent event_mask);
104
105   /* Wakes up the scheduler. This is platform specific routine */
106   void (*wakeup)(SilcSchedule schedule, void *context);
107
108   /* Register signal */
109   void (*signal_register)(SilcSchedule schedule, void *context,
110                           SilcUInt32 signal, SilcTaskCallback callback,
111                           void *callback_context);
112
113   /* Unregister signal */
114   void (*signal_unregister)(SilcSchedule schedule, void *context,
115                             SilcUInt32 signal);
116
117   /* Call all signals */
118   void (*signals_call)(SilcSchedule schedule, void *context);
119
120   /* Block registered signals in scheduler. */
121   void (*signals_block)(SilcSchedule schedule, void *context);
122
123   /* Unblock registered signals in schedule. */
124   void (*signals_unblock)(SilcSchedule schedule, void *context);
125 } SilcScheduleOps;
126
127 /* The generic function to add any type of task to the scheduler.  This
128    used to be exported as is to application, but now they should use the
129    macro wrappers defined in silcschedule.h.  For Fd task the timeout must
130    be zero, for timeout task the timeout must not be zero, for signal task
131    the fd argument is the signal. */
132 SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
133                                 SilcTaskCallback callback, void *context,
134                                 long seconds, long useconds,
135                                 SilcTaskType type);
136
137 #ifdef SILC_DIST_INPLACE
138 /* Print scheduler statistics to stdout. */
139 void silc_schedule_stats(SilcSchedule schedule);
140 #endif /* SILC_DIST_INPLACE */
141
142 #endif /* SILCSCHEDULE_I_H */