1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Files
2024-07-22 01:58:46 -03:00

114 lines
2.2 KiB
C

/* dispatch.c - Event dispatcher */
/* Written 1998 by Werner Almesberger, EPFL ICA */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include "atmd.h"
#include "dispatch.h"
typedef struct _fd_entry {
int fd;
void (*callback)(int fd,void *user);
void *user;
struct _fd_entry *next;
} FD_ENTRY;
static FD_ENTRY *fd_idle = NULL,*fd_active = NULL;
static int fds = 0;
static fd_set r_set;
void dsp_fd_add(int fd,void (*callback)(int fd,void *user),void *user)
{
FD_ENTRY *entry;
for (entry = fd_idle; entry; entry = entry->next)
if (entry->fd == fd) break;
if (!entry)
for (entry = fd_active; entry; entry = entry->next)
if (entry->fd == fd) break;
if (entry) {
fprintf(stderr,"dsp_fd_add: duplicate fd %d\n",fd);
exit(1);
}
if (fd >= fds) fds = fd+1;
FD_SET(fd,&r_set);
entry = alloc_t(FD_ENTRY);
entry->fd = fd;
entry->callback = callback;
entry->user = user;
entry->next = fd_idle;
fd_idle = entry;
}
void dsp_fd_remove(int fd)
{
FD_ENTRY **walk,*next;
FD_CLR(fd,&r_set);
for (walk = &fd_idle; *walk; walk = &(*walk)->next) {
if ((*walk)->fd != fd) continue;
next = (*walk)->next;
free(*walk);
*walk = next;
return;
}
for (walk = &fd_active; *walk; walk = &(*walk)->next) {
if ((*walk)->fd != fd) continue;
next = (*walk)->next;
free(*walk);
*walk = next;
return;
}
fprintf(stderr,"dsp_fd_remove: fd %d not found\n",fd);
exit(1);
}
void dsp_init(void)
{
FD_ZERO(&r_set);
}
void dsp_poll(void)
{
FD_ENTRY **walk,*next,*entry;
fd_set r_poll;
int num;
while (!fd_active) {
r_poll = r_set;
num = select(fds+1,&r_poll,NULL,NULL,NULL);
if (num < 0) {
if (errno != EINTR) perror("select");
continue;
}
for (walk = &fd_idle; num;) {
next = (*walk)->next;
if (!FD_ISSET((*walk)->fd,&r_poll)) {
walk = &(*walk)->next;
continue;
}
(*walk)->next = fd_active;
fd_active = *walk;
*walk = next;
num--;
}
}
entry = fd_active;
fd_active = entry->next;
entry->next = fd_idle;
fd_idle = entry;
entry->callback(entry->fd,entry->user);
}