2004-08-12 01:07:22 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
|
2004-08-13 01:38:15 -04:00
|
|
|
void init_io_tasks(fd_set* fdset, IO_TASK* io_tasks)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
FD_ZERO(fdset);
|
|
|
|
|
for(i = 0; i < FD_SETSIZE; i++)
|
|
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
read_io_tasks[i].port = F;
|
2004-08-13 01:38:15 -04:00
|
|
|
read_io_tasks[i].callback = F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-12 01:07:22 -04:00
|
|
|
void init_iomux(void)
|
|
|
|
|
{
|
2004-08-13 01:38:15 -04:00
|
|
|
read_fd_count = 0;
|
|
|
|
|
init_io_tasks(&read_fd_set,read_io_tasks);
|
|
|
|
|
|
|
|
|
|
write_fd_count = 0;
|
|
|
|
|
init_io_tasks(&write_fd_set,write_io_tasks);
|
2004-08-12 01:07:22 -04:00
|
|
|
}
|
|
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
void add_io_task_impl(
|
|
|
|
|
IO_TASK_TYPE type,
|
2004-08-13 01:38:15 -04:00
|
|
|
PORT* port,
|
|
|
|
|
CELL callback,
|
|
|
|
|
fd_set* fdset,
|
|
|
|
|
IO_TASK* io_tasks,
|
|
|
|
|
int* fd_count)
|
2004-08-12 01:07:22 -04:00
|
|
|
{
|
2004-08-13 01:38:15 -04:00
|
|
|
int fds = *fd_count;
|
|
|
|
|
|
2004-08-12 01:07:22 -04:00
|
|
|
/* Look for an empty slot first */
|
|
|
|
|
int i;
|
2004-08-13 01:38:15 -04:00
|
|
|
for(i = 0; i < fds; i++)
|
2004-08-12 01:07:22 -04:00
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
if(io_tasks[i].port == F)
|
2004-08-12 01:07:22 -04:00
|
|
|
{
|
2004-08-13 01:38:15 -04:00
|
|
|
FD_SET(port->fd,fdset);
|
2004-08-13 02:19:22 -04:00
|
|
|
io_tasks[i].type = type;
|
|
|
|
|
io_tasks[i].port = tag_object(port);
|
2004-08-13 01:38:15 -04:00
|
|
|
io_tasks[i].callback = callback;
|
2004-08-12 01:07:22 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-13 01:38:15 -04:00
|
|
|
/* add at end */
|
|
|
|
|
if(fds == FD_SETSIZE)
|
|
|
|
|
critical_error("Too many I/O tasks",*fd_count);
|
|
|
|
|
|
|
|
|
|
FD_SET(port->fd,fdset);
|
2004-08-13 02:19:22 -04:00
|
|
|
io_tasks[fds].type = type;
|
|
|
|
|
io_tasks[fds].port = tag_object(port);
|
2004-08-13 01:38:15 -04:00
|
|
|
io_tasks[fds].callback = callback;
|
|
|
|
|
*fd_count = fds + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
void add_io_task(IO_TASK_TYPE type, PORT* port, CELL callback)
|
2004-08-13 01:38:15 -04:00
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case IO_TASK_READ_LINE:
|
|
|
|
|
case IO_TASK_READ_COUNT:
|
|
|
|
|
add_io_task_impl(type,port,callback,
|
|
|
|
|
&read_fd_set,read_io_tasks,
|
|
|
|
|
&read_fd_count);
|
|
|
|
|
break;
|
|
|
|
|
case IO_TASK_WRITE:
|
|
|
|
|
add_io_task_impl(type,port,callback,
|
|
|
|
|
&write_fd_set,write_io_tasks,
|
|
|
|
|
&write_fd_count);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-08-13 01:38:15 -04:00
|
|
|
}
|
|
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
void remove_io_task_impl(
|
|
|
|
|
IO_TASK_TYPE type,
|
2004-08-13 01:38:15 -04:00
|
|
|
PORT* port,
|
|
|
|
|
fd_set* fdset,
|
|
|
|
|
IO_TASK* io_tasks,
|
|
|
|
|
int* fd_count)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int fds = *fd_count;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < fds; i++)
|
|
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
if(untag_port(io_tasks[i].port) == port)
|
2004-08-13 01:38:15 -04:00
|
|
|
{
|
|
|
|
|
FD_CLR(port->fd,fdset);
|
2004-08-13 02:19:22 -04:00
|
|
|
io_tasks[i].port = F;
|
2004-08-13 01:38:15 -04:00
|
|
|
io_tasks[i].callback = F;
|
|
|
|
|
if(i == fds - 1)
|
|
|
|
|
*fd_count = fds - 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
void remove_io_task(IO_TASK_TYPE type, PORT* port)
|
2004-08-13 01:38:15 -04:00
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case IO_TASK_READ_LINE:
|
|
|
|
|
case IO_TASK_READ_COUNT:
|
|
|
|
|
remove_io_task_impl(type,port,
|
|
|
|
|
&read_fd_set,read_io_tasks,
|
|
|
|
|
&read_fd_count);
|
|
|
|
|
break;
|
|
|
|
|
case IO_TASK_WRITE:
|
|
|
|
|
remove_io_task_impl(type,port,
|
|
|
|
|
&write_fd_set,write_io_tasks,
|
|
|
|
|
&write_fd_count);
|
|
|
|
|
}
|
2004-08-13 01:38:15 -04:00
|
|
|
}
|
|
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
void perform_iotask(IO_TASK* task)
|
2004-08-13 01:38:15 -04:00
|
|
|
{
|
2004-08-13 02:19:22 -04:00
|
|
|
if(task->port == F)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch(task->type)
|
|
|
|
|
{
|
|
|
|
|
case IO_TASK_READ_LINE:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case IO_TASK_WRITE:
|
|
|
|
|
write_step(untag_port(task->port));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
critical_error("Bad I/O task",task->type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-08-13 01:38:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Wait for I/O and return a callback. */
|
|
|
|
|
CELL iomux(void)
|
|
|
|
|
{
|
|
|
|
|
int nfds = select(read_fd_count > write_fd_count
|
|
|
|
|
? read_fd_count : write_fd_count,
|
|
|
|
|
&read_fd_set,&write_fd_set,NULL,NULL);
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2004-08-13 02:19:22 -04:00
|
|
|
/* int i;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < read_fd_count; i++)
|
|
|
|
|
perform_iotask(&read_io_tasks[i]);
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < write_fd_count; i++)
|
|
|
|
|
perform_iotask(&write_io_tasks[i]); */
|
|
|
|
|
|
2004-08-13 01:38:15 -04:00
|
|
|
return F;
|
2004-08-12 01:07:22 -04:00
|
|
|
}
|
2004-08-13 02:19:22 -04:00
|
|
|
|
|
|
|
|
void collect_io_tasks(void)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < FD_SETSIZE; i++)
|
|
|
|
|
{
|
|
|
|
|
copy_object(&read_io_tasks[i].port);
|
|
|
|
|
copy_object(&read_io_tasks[i].callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < FD_SETSIZE; i++)
|
|
|
|
|
{
|
|
|
|
|
copy_object(&write_io_tasks[i].port);
|
|
|
|
|
copy_object(&write_io_tasks[i].callback);
|
|
|
|
|
}
|
|
|
|
|
}
|