Author: Pekka Riikonen <priikone@silcnet.org>
- 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
#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 */
/* 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;
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 */
};
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 */
/* 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);
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 */