Commit 458b2455 authored by Niels Möller's avatar Niels Möller
Browse files

* src/io.c: Deleted old backend code.

(io_run): Check for OOP_ERROR. #if:ed out for now, as it is not
defined in liboop-0.7.

Rev: src/io.c:1.151
parent 1e5698d0
......@@ -110,10 +110,15 @@ io_final(void)
void
io_run(void)
{
oop_sys_run(global_oop_sys);
void *res = oop_sys_run(global_oop_sys);
/* FIXME: Check for OOP_ERROR */
/* FIXME: OOP_ERROR is not defined in liboop-0.7. Upgrade, and then
* enable this check. */
#if 0
if (res == OOP_ERROR)
werror("oop_sys_run (errno = %i): %z\n",
errno, STRERROR(errno));
#endif
trace("io_run: Exiting\n");
}
......@@ -296,344 +301,6 @@ lsh_oop_cancel_callout(struct lsh_callout *callout)
(action object lsh_callback)))
*/
/* FIXME: With liboop, we should not need this object, we'd only need
* a resource_list owned by the gc. */
/* ;; GABA:
(class
(name io_backend)
(super resource)
(vars
; Linked list of fds.
(files object lsh_fd)
; Signal handlers
(signals object lsh_signal_handler)
; Callouts
(callouts object lsh_callout)))
*/
/* Backend loop */
/* If there's nothing to do for this amount of time (ms), do
* spontaneous gc. */
#define IDLE_TIME 100
#if 0
int io_iter(struct io_backend *b)
{
unsigned long nfds; /* FIXME: Should be nfds_t if that type is defined */
struct pollfd *fds;
struct lsh_fd **active_fds;
/* FIXME: Real scheduling of callouts not implemented */
/* int timeout; */
int res;
/* Check all flags */
if (b->signals)
{
struct lsh_signal_handler *f;
struct lsh_signal_handler **f_p;
for (f_p = &b->signals; (f = *f_p); )
{
if (!f->super.alive)
*f_p = f->next;
else
{
if (*f->flag)
{
*f->flag = 0;
LSH_CALLBACK(f->action);
}
f_p = &f->next;
}
}
}
/* Invoke all callouts. Clear the list first; if any callout
* installs another one, that will not be invoked until the next
* iteration. */
if (b->callouts)
{
struct lsh_callout *p;
for (p = b->callouts, b->callouts = NULL;
p; p = p->next)
if (p->super.alive)
{
LSH_CALLBACK(p->action);
p->super.alive = 0;
}
}
/* Prepare fds. */
{
struct lsh_fd *fd;
for (fd = b->files; fd; fd = fd->next)
/* NOTE: The prepare callback is allowed to close files. */
if (fd->super.alive && fd->prepare)
FD_PREPARE(fd);
}
/* This phase unlinks any closed fd:s, and also counts how many
* fd:s there are. */
{
struct lsh_fd *fd;
struct lsh_fd **fd_p;
nfds = 0;
for(fd_p = &b->files; (fd = *fd_p); )
{
if (!fd->super.alive)
/* Unlink this fd */
*fd_p = fd->next;
else
{
if (fd->want_read || fd->want_write)
nfds++;
fd_p = &fd->next;
}
}
}
if (!nfds)
/* Nothing more to do.
*
* NOTE: There might be some callouts left, but we won't wait for them. */
return 0;
fds = alloca(sizeof(struct pollfd) * nfds);
active_fds = alloca(sizeof(struct lsh_fd *) *nfds);
/* Fill out fds-array */
{
struct lsh_fd *fd;
unsigned long i;
int all_events = 0;
for (fd = b->files, i = 0; fd; fd = fd->next)
{
assert(fd->super.alive);
if (fd->want_read || fd->want_write)
{
assert(i < nfds);
active_fds[i] = fd;
fds[i].fd = fd->fd;
fds[i].events = 0;
if (fd->want_read)
fds[i].events |= MY_POLLIN;
if (fd->want_write)
fds[i].events |= POLLOUT;
all_events |= fds[i].events;
i++;
}
}
assert(i == nfds);
assert(all_events);
}
res = poll(fds, nfds, IDLE_TIME);
if (!res)
{
gc_maybe(&b->super.super, 0);
res = poll(fds, nfds, -1);
}
else
gc_maybe(&b->super.super, 1);
if (!res)
{
/* Callouts are not implemented */
fatal("Unexpected timeout\n");
}
if (res < 0)
switch(errno)
{
case EAGAIN:
case EINTR:
return 1;
default:
fatal("io_iter: poll failed: %z", STRERROR(errno));
}
{
/* Do io. Note that the callback functions may add new fds to the
* head of the list, or clear the alive flag on any fd. But this
* is less of a problem now, as we use the active_fd array.*/
/* struct lsh_fd *fd; */
unsigned long i;
for(i=0; i<nfds; i++)
{
struct lsh_fd *fd = active_fds[i];
assert(i<nfds);
debug("io.c: poll for fd %i: events = 0x%xi, revents = 0x%xi.\n",
fds[i].fd, fds[i].events, fds[i].revents);
if (!fd->super.alive)
continue;
/* On systems without poll, we use jpoll.c to emulate some
* of poll, but we lack POLLNVAL, POLLPRI and POLLHUP. */
#ifdef POLLNVAL
if (fds[i].revents & POLLNVAL)
{
werror("io.c: poll request on fd %i, for events of type %xi\n"
" return POLLNVAL, revents = %xi\n",
fds[i].fd, fds[i].events, fds[i].revents);
close_fd(fd);
continue;
}
#endif /* POLLNVAL */
#ifdef POLLHUP
/* NOTE: The behaviour of poll at EOF varies quite a lot
* between systems.
*
* According to Solaris' man page, POLLHUP is mutually
* exclusive with POLLOUT, but orthogonal to POLLIN.
*
* However, on my system (sparc-linux) POLLHUP is set when we
* get EOF on an fd we are reading.
*
* I.e. on some systems, EOF is indicated by poll setting
* POLLIN and read returning 0 (in particular, this happens
* if the poll-by-select-code in jpoll.c is used), while on
* other systems, poll sets POLLHUP and subsequent read
* calls will return -1, not 0.
*
* But to complicate things some more, we can (also on Linux)
* get both POLLHUP and POLLIN set. In that case, we do an
* ordinary read.
*
* We set the hanged_up flag before calling FD_READ, which
* tells the io_callback that it should avoid calling read. */
if (fds[i].revents & POLLHUP)
{
if (fd->want_write)
/* Will raise an i/o error */
FD_WRITE(fd);
else if (fd->want_read)
{
if (!fd->super.alive)
continue;
/* If reading is not possible, treat this as EOF. */
if (!(fds[i].revents & MY_POLLIN))
fd->hanged_up = 1;
FD_READ(fd);
}
else
{
werror("io.c: poll said POLLHUP on an inactive fd.\n");
close_fd(fd);
}
continue;
}
#endif /* POLLHUP */
#ifdef POLLERR
if (fds[i].revents & POLLERR)
{
werror("io.c: POLLERR. Hanging up.\n");
/* FIXME: Should we raise any exception here? */
close_fd(fd);
continue;
}
#endif /* POLLERR */
#ifdef POLLPRI
if (fds[i].revents & POLLPRI)
{
werror("io.c: Peer is trying to send Out of Band data. Hanging up.\n");
/* FIXME: Should we raise any exception here? */
close_fd(fd);
continue;
}
#endif /* POLLPRI */
if (fds[i].revents & POLLOUT)
FD_WRITE(fd);
if (!fd->super.alive)
continue;
if (fds[i].revents & MY_POLLIN)
FD_READ(fd);
}
assert(i == nfds);
}
return 1;
}
#endif
#if 0
static void
do_kill_io_backend(struct resource *s)
{
CAST(io_backend, backend, s);
if (backend->super.alive)
{
struct lsh_fd *fd;
struct lsh_signal_handler *signal;
for (fd = backend->files, backend->files = NULL;
fd; fd = fd->next)
close_fd(fd);
/* Check that no callback has opened new files. */
assert(!backend->files);
/* FIXME: Use a resource list instead? */
for (signal = backend->signals, backend->signals = NULL;
signal; signal = signal->next)
KILL_RESOURCE(&signal->super);
backend->super.alive = 0;
}
}
#endif
#if 0
struct io_backend *
make_io_backend(void)
{
NEW(io_backend, b);
io_init();
init_resource(&b->super, do_kill_io_backend);
b->files = NULL;
b->signals = NULL;
b->callouts = NULL;
return b;
}
#endif
static void
do_kill_signal_handler(struct resource *s)
......@@ -850,6 +517,7 @@ do_consuming_read(struct io_callback *c,
* EPIPE, but it happens occasionally under linux. Perhaps
* we should treat it as EOF instead? */
werror("io.c: read_consume: Unexpected EPIPE.\n");
/* Fall through */
default:
EXCEPTION_RAISE(fd->e,
make_io_exception(EXC_IO_READ,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment