X-Git-Url: http://git.silcnet.org/gitweb/?p=crypto.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcschedule_i.h;h=a88df592c8fb7bad88b4f183e16b50dc7a2d3cc8;hp=6853d253a0491cc95edaf97f3ebeda648628939e;hb=60180da59ffdbbd12058dded66e3c8a547cd0852;hpb=4c6c24cc5513d0725b6a4afd2ce30acbedd65ab2 diff --git a/lib/silcutil/silcschedule_i.h b/lib/silcutil/silcschedule_i.h index 6853d253..a88df592 100644 --- a/lib/silcutil/silcschedule_i.h +++ b/lib/silcutil/silcschedule_i.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2006 Pekka Riikonen + Copyright (C) 2001 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,42 +27,77 @@ #include "silchashtable.h" #include "silclist.h" +/* Task types */ +typedef enum { + /* File descriptor task that performs some event over file descriptors. + These tasks are for example network connections. */ + 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 + task in task callback. It is also safe to unregister a task in + the task callback. */ + SILC_TASK_TIMEOUT = 1, + + /* Platform specific process signal task. On Unix systems this is one of + the signals described in signal(7). On other platforms this may not + be available at all. Only one callback per signal may be added. */ + SILC_TASK_SIGNAL = 2, + + /* Asynchronous event task. */ + SILC_TASK_EVENT = 3, +} SilcTaskType; + /* Task header */ struct SilcTaskStruct { + struct SilcTaskStruct *next; SilcTaskCallback callback; void *context; - unsigned int type : 1; /* 0 = fd, 1 = timeout */ + unsigned int type : 2; /* SilcTaskType */ unsigned int valid : 1; /* Set if task is valid */ }; /* Timeout task */ typedef struct SilcTaskTimeoutStruct { struct SilcTaskStruct header; - struct SilcTaskTimeoutStruct *next; struct timeval timeout; } *SilcTaskTimeout; /* Fd task */ -typedef struct { +typedef struct SilcTaskFdStruct { struct SilcTaskStruct header; - unsigned int events : 15; - unsigned int revents : 15; + unsigned int scheduled : 1; + unsigned int events : 14; + unsigned int revents : 14; SilcUInt32 fd; } *SilcTaskFd; +/* Event task */ +typedef struct SilcEventTaskStruct { + struct SilcTaskStruct header; + char *event; + SilcList connections; +} *SilcEventTask; + /* Scheduler context */ struct SilcScheduleStruct { + SilcSchedule parent; /* Parent scheduler */ void *internal; void *app_context; /* Application specific context */ + SilcTaskNotifyCb notify; /* Notify callback */ + void *notify_context; /* Notify context */ + SilcStack stack; /* Stack */ + SilcHashTable events; /* Event tasks */ SilcHashTable fd_queue; /* FD task queue */ + SilcList fd_dispatch; /* Dispatched FDs */ SilcList timeout_queue; /* Timeout queue */ SilcList free_tasks; /* Timeout task freelist */ SilcMutex lock; /* Scheduler lock */ struct timeval timeout; /* Current timeout */ - unsigned int max_tasks : 28; /* Max FD tasks */ + unsigned int max_tasks : 29; /* Max FD tasks */ unsigned int has_timeout : 1; /* Set if timeout is set */ unsigned int valid : 1; /* Set if scheduler is valid */ - unsigned int is_locked : 1; /* Set if scheduler is locked */ unsigned int signal_tasks : 1; /* Set if to dispatch signals */ }; @@ -71,13 +106,13 @@ struct SilcScheduleStruct { synchronise signals with SILC Scheduler. */ #define SILC_SCHEDULE_LOCK(schedule) \ do { \ - schedule_ops.signals_block(schedule, schedule->internal); \ silc_mutex_lock(schedule->lock); \ + schedule_ops.signals_block(schedule, schedule->internal); \ } while (0) #define SILC_SCHEDULE_UNLOCK(schedule) \ do { \ - silc_mutex_unlock(schedule->lock); \ schedule_ops.signals_unblock(schedule, schedule->internal); \ + silc_mutex_unlock(schedule->lock); \ } while (0) /* Platform specific scheduler operations */ @@ -85,14 +120,22 @@ typedef struct { /* Initializes the platform specific scheduler. This for example initializes the wakeup mechanism of the scheduler. In multi-threaded environment the scheduler needs to be wakenup when tasks are added or removed from - the task queues. Returns context to the platform specific scheduler. */ + the task queues. Returns context to the platform specific scheduler. + If this returns NULL the scheduler initialization will fail. Do not + add FD tasks inside function. Timeout tasks can be added. */ void *(*init)(SilcSchedule schedule, void *app_context); /* Uninitializes the platform specific scheduler context. */ void (*uninit)(SilcSchedule schedule, void *context); - /* System specific select(). Returns same values as normal select(). */ - int (*select)(SilcSchedule schedule, void *context); + /* System specific waiter. This must fill the schedule->fd_dispatch queue + with valid tasks that has something to dispatch, when this returns. */ + int (*schedule)(SilcSchedule schedule, void *context); + + /* Schedule `task' with events `event_mask'. Zero `event_mask' + unschedules the task. */ + SilcBool (*schedule_fd)(SilcSchedule schedule, void *context, + SilcTaskFd task, SilcTaskEvent event_mask); /* Wakes up the scheduler. This is platform specific routine */ void (*wakeup)(SilcSchedule schedule, void *context); @@ -126,9 +169,9 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, long seconds, long useconds, SilcTaskType type); -#if defined(SILC_DEBUG) +#ifdef SILC_DIST_INPLACE /* Print scheduler statistics to stdout. */ void silc_schedule_stats(SilcSchedule schedule); -#endif /* SILC_DEBUG */ +#endif /* SILC_DIST_INPLACE */ #endif /* SILCSCHEDULE_I_H */