Commit 2a476d30 authored by Niels Möller's avatar Niels Möller

New conventions for the return values from abstract_read-functions.

Use the same list for input- and output-fd:s.

Rev: src/io.c:1.3
Rev: src/io.h:1.3
parent e3277770
...@@ -22,14 +22,25 @@ struct fd_read ...@@ -22,14 +22,25 @@ struct fd_read
static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length) static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length)
{ {
int res; while(1)
do {
res = read(closure->fd, buffer, length); int res = read(closure->fd, buffer, length);
while ( (res < 0) if (!res)
&& ( (errno == EINTR) return A_EOF;
|| (errno == EAGAIN) ) ); if (res > 0)
return res; return res;
};
switch(errno)
{
case EINTR:
continue;
case EWOULDBLOCK: /* aka EAGAIN */
return 0;
default:
return A_FAIL;
}
}
}
#define FOR_FDS(type, fd, list, extra) \ #define FOR_FDS(type, fd, list, extra) \
{ \ { \
...@@ -51,7 +62,7 @@ void io_run(struct io_backend *b) ...@@ -51,7 +62,7 @@ void io_run(struct io_backend *b)
int timeout; int timeout;
int res; int res;
nfds = b->ninput + b->noutput + b->nlisten + n->nconnect; nfds = b->nio + b->nlisten + n->nconnect;
if (b->callouts) if (b->callouts)
{ {
...@@ -79,10 +90,14 @@ void io_run(struct io_backend *b) ...@@ -79,10 +90,14 @@ void io_run(struct io_backend *b)
/* Handle fds in order: read, accept, connect, write, */ /* Handle fds in order: read, accept, connect, write, */
i = 0; i = 0;
FOR_FDS(struct input_fd, fd, b->input, i++) FOR_FDS(struct io_fd, fd, b->io, i++)
{ {
fds[i]->fd = fd->hold_on ? -1 : fd->fd; fds[i]->fd = fd->hold_on ? -1 : fd->fd;
fds[i]->events = POLLIN; fds[i]->events =
(fd->hold_on ? 0 : POLLIN)
/* pre_write returns 0 if the buffer is empty */
| (write_buffer_pre_write(fd->buffer)
? POLLOUT : 0);
} }
END_FOR_FDS; END_FOR_FDS;
...@@ -100,15 +115,6 @@ void io_run(struct io_backend *b) ...@@ -100,15 +115,6 @@ void io_run(struct io_backend *b)
} }
END_FOR_FDS; END_FOR_FDS;
FOR_FDS(struct output_fd, fd, b->output, i++)
{
/* pre_write returns 0 if the buffer is empty */
fds[i]->fd = write_buffer_pre_write(fd->buffer)
? fd->fd : -1
fds[i]->events = POLLOUT;
}
END_FOR_FDS;
res = poll(fds, nfds, timeout); res = poll(fds, nfds, timeout);
if (!res) if (!res)
...@@ -136,14 +142,50 @@ void io_run(struct io_backend *b) ...@@ -136,14 +142,50 @@ void io_run(struct io_backend *b)
{ /* Process files */ { /* Process files */
i = 0; i = 0;
FOR_FDS(struct input_fd, fd, b->input, i++) /* Handle writing first */
FOR_FDS(struct io_fd, fd, b->io, i++)
{
if (fds[i]->revents & POLLOUT)
{
UINT32 size = MIN(fd->buffer->end - fd->buffer->start,
fd->buffer->block_size);
int res = write(fd->fd, fd->buffer->data + fd->buffer->start,
size);
if (!res)
fatal("Closed?");
if (res < 0)
switch(errno)
{
case EINTR:
case EAGAIN:
break;
default:
CALLBACK(fd->close_callback);
/* FIXME: Must do this later. Perhaps add a
* closed flag to th io_fd struct? */
#if 0
UNLINK_FD;
free(fd->write_buffer);
free(fd);
#endif
break;
}
else
fd->buffer->start += res;
}
}
END_FOR_FDS;
/* Handle reading */
i = 0; /* Start over */
FOR_FDS(struct io_fd, fd, b->io, i++)
{ {
if (fds[i]->revents & POLLIN) if (fds[i]->revents & POLLIN)
{ {
struct fd_read r = struct fd_read r =
{ { (abstract_read_f) do_read }, fd->fd }; { { (abstract_read_f) do_read }, fd->fd, 0 };
/* The handler function returns a ew handler for the /* The handler function returns a new handler for the
* file, or NULL. */ * file, or NULL. */
if (!(fd->handler = READ_HANDLER(fd->handler, &r))) if (!(fd->handler = READ_HANDLER(fd->handler, &r)))
{ {
...@@ -187,35 +229,6 @@ void io_run(struct io_backend *b) ...@@ -187,35 +229,6 @@ void io_run(struct io_backend *b)
} }
} }
END_FOR_FDS; END_FOR_FDS;
FOR_FDS(struct output_fd, fd, b->output, i++)
{
if (fds[i]->revents & POLLOUT)
{
UINT32 size = MIN(fd->buffer->end - fd->buffer->start,
fd->buffer->block_size);
int res = write(fd->fd, fd->buffer->data + fd->buffer->start,
size);
if (!res)
fatal("Closed?");
if (res < 0)
switch(errno)
{
case EINTR:
case EAGAIN:
break;
default:
CALLBACK(fd->close_Callback);
UNLINK_FD;
free(fd->write_buffer);
free(fd);
break;
}
else
fd->buffer->start += res;
}
}
END_FOR_FDS;
} }
} }
} }
......
...@@ -8,18 +8,16 @@ ...@@ -8,18 +8,16 @@
#include "abstract_io.h" #include "abstract_io.h"
#include "write_buffer.h" #include "write_buffer.h"
struct input_fd struct io_fd
{ {
struct input_fd *next; struct io_fd *next;
int fd; int fd;
/* Reading */
struct read_handler *handler; struct read_handler *handler;
int on_hold; /* For flow control */ int on_hold; /* For flow control */
};
struct output_fd /* Writing */
{
struct output_fd *next;
int fd;
struct write_buffer *buffer; struct write_buffer *buffer;
struct callback *close_callback; struct callback *close_callback;
}; };
...@@ -59,10 +57,8 @@ struct callout ...@@ -59,10 +57,8 @@ struct callout
struct io_backend struct io_backend
{ {
unsigned ninput; unsigned nio;
struct input_fd *input; struct io_fd *io;
unsigned noutput;
struct output_fd *output;
unsigned nlisten; unsigned nlisten;
struct listen_fd *listen; struct listen_fd *listen;
unsigned nconnect; unsigned nconnect;
......
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