struct pollfd *fds = internal->fds;
SilcUInt32 fds_count = internal->fds_count;
int fd, ret, i = 0, timeout = -1;
+ void *fdp;
silc_hash_table_list(schedule->fd_queue, &htl);
- while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+ while (silc_hash_table_get(&htl, &fdp, (void *)&task)) {
if (!task->events)
continue;
+ fd = SILC_PTR_TO_32(fdp);
/* Allocate larger fd table if needed */
if (i >= fds_count) {
if (!fds[i].revents)
continue;
if (!silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fds[i].fd),
- NULL, (void **)&task))
+ NULL, (void *)&task))
continue;
if (!task->header.valid || !task->events)
continue;
SilcTaskFd task;
fd_set in, out;
int fd, max_fd = 0, ret;
+ void *fdp;
FD_ZERO(&in);
FD_ZERO(&out);
silc_hash_table_list(schedule->fd_queue, &htl);
- while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+ while (silc_hash_table_get(&htl, &fdp, (void *)&task)) {
if (!task->events)
continue;
+ fd = SILC_PTR_TO_32(fdp);
#ifdef FD_SETSIZE
if (fd >= FD_SETSIZE)
return ret;
silc_hash_table_list(schedule->fd_queue, &htl);
- while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task)) {
+ while (silc_hash_table_get(&htl, &fdp, (void *)&task)) {
if (!task->header.valid || !task->events)
continue;
+ fd = SILC_PTR_TO_32(fdp);
#ifdef FD_SETSIZE
if (fd >= FD_SETSIZE)
SILC_LOG_DEBUG(("Scheduling fd %lu, mask %x", task->fd, event_mask));
- event.events = 0;
+ memset(&event, 0, sizeof(event));
if (event_mask & SILC_TASK_READ)
event.events |= (EPOLLIN | EPOLLPRI);
if (event_mask & SILC_TASK_WRITE)
SILC_LOG_DEBUG(("Wokeup"));
- read(internal->wakeup_pipe[0], &c, 1);
+ (void)read(internal->wakeup_pipe[0], &c, 1);
}
+SILC_TASK_CALLBACK(silc_schedule_wakeup_init)
+{
+ SilcUnixScheduler internal = schedule->internal;
+
+ internal->wakeup_task =
+ silc_schedule_task_add(schedule, internal->wakeup_pipe[0],
+ silc_schedule_wakeup_cb, internal,
+ 0, 0, SILC_TASK_FD);
+ if (!internal->wakeup_task) {
+ SILC_LOG_WARNING(("Could not add a wakeup task, threads won't work"));
+ close(internal->wakeup_pipe[0]);
+ return;
+ }
+ silc_schedule_internal_schedule_fd(schedule, internal,
+ (SilcTaskFd)internal->wakeup_task,
+ SILC_TASK_READ);
+}
#endif /* SILC_THREADS */
/* 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 scheduler needs to be woken up when tasks are added or removed from
the task queues. Returns context to the platform specific scheduler. */
void *silc_schedule_internal_init(SilcSchedule schedule,
SilcUnixScheduler internal;
int i;
- internal = silc_calloc(1, sizeof(*internal));
+ internal = silc_scalloc(schedule->stack, 1, sizeof(*internal));
if (!internal)
return NULL;
#ifdef SILC_THREADS
if (pipe(internal->wakeup_pipe)) {
SILC_LOG_ERROR(("pipe() fails: %s", strerror(errno)));
- silc_free(internal);
return NULL;
}
- internal->wakeup_task =
- silc_schedule_task_add(schedule, internal->wakeup_pipe[0],
- silc_schedule_wakeup_cb, internal,
- 0, 0, SILC_TASK_FD);
- if (!internal->wakeup_task) {
- SILC_LOG_ERROR(("Could not add a wakeup task, threads won't work"));
- close(internal->wakeup_pipe[0]);
- close(internal->wakeup_pipe[1]);
- silc_free(internal);
- return NULL;
- }
-#endif
- silc_schedule_internal_schedule_fd(schedule, internal,
- (SilcTaskFd)internal->wakeup_task,
- SILC_TASK_READ);
+ silc_schedule_task_add_timeout(schedule, silc_schedule_wakeup_init,
+ internal, 0, 0);
+#endif /* SILC_THREADS */
internal->app_context = app_context;
#elif defined(HAVE_POLL) && defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
silc_free(internal->fds);
#endif /* HAVE_POLL && HAVE_SETRLIMIT && RLIMIT_NOFILE */
-
- silc_free(internal);
}
/* Wakes up the scheduler */
#ifdef SILC_THREADS
SilcUnixScheduler internal = (SilcUnixScheduler)context;
- if (!internal)
+ if (!internal || !internal->wakeup_task)
return;
SILC_LOG_DEBUG(("Wakeup"));
- write(internal->wakeup_pipe[1], "!", 1);
+ (void)write(internal->wakeup_pipe[1], "!", 1);
#endif
}
{
int i;
+ SILC_LOG_DEBUG(("Start"));
+
for (i = 0; i < SIGNAL_COUNT; i++) {
if (signal_call[i].sig == signal) {
signal_call[i].call = TRUE;
signal_call[i].sig = sig;
signal_call[i].callback = callback;
signal_call[i].context = callback_context;
+ signal_call[i].schedule = schedule;
signal_call[i].call = FALSE;
signal(sig, silc_schedule_internal_sighandler);
break;
signal_call[i].sig = 0;
signal_call[i].callback = NULL;
signal_call[i].context = NULL;
+ signal_call[i].schedule = NULL;
signal_call[i].call = FALSE;
signal(sig, SIG_DFL);
}
signal_call[i].callback) {
SILC_LOG_DEBUG(("Calling signal %d callback",
signal_call[i].sig));
+ silc_schedule_internal_signals_unblock(schedule, context);
signal_call[i].callback(schedule, internal->app_context,
SILC_TASK_INTERRUPT,
signal_call[i].sig,
signal_call[i].context);
signal_call[i].call = FALSE;
+ silc_schedule_internal_signals_block(schedule, context);
}
}