X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcschedule_i.h;h=61ea48125a0d96d374db7f2730fd8d95cd6a2adc;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=c7135393788ee109f51c46a71e429703650e89c3;hpb=43af8f1735ca8be4f582db3dc4a90dd339b60532;p=silc.git diff --git a/lib/silcutil/silcschedule_i.h b/lib/silcutil/silcschedule_i.h index c7135393..61ea4812 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,8 +27,28 @@ #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, + + /* 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 +} SilcTaskType; + /* Task header */ struct SilcTaskStruct { + struct SilcTaskStruct *next; SilcTaskCallback callback; void *context; unsigned int type : 1; /* 0 = fd, 1 = timeout */ @@ -38,15 +58,15 @@ struct SilcTaskStruct { /* 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 : 15; SilcUInt32 fd; } *SilcTaskFd; @@ -54,15 +74,17 @@ typedef struct { struct SilcScheduleStruct { void *internal; void *app_context; /* Application specific context */ + SilcTaskNotifyCb notify; /* Notify callback */ + void *notify_context; /* Notify context */ 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 +93,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 +107,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);