Commit d4cd2417 authored by Niels Möller's avatar Niels Möller

Made lsh_fd a subclass of resource. Use the super.alive field instead

of close_now.

Rev: src/io.c:1.35
Rev: src/io.h:1.23
parent 774f453b
...@@ -78,10 +78,10 @@ int io_iter(struct io_backend *b) ...@@ -78,10 +78,10 @@ int io_iter(struct io_backend *b)
for(fd_p = &b->files; (fd = *fd_p); ) for(fd_p = &b->files; (fd = *fd_p); )
{ {
if (!fd->close_now && fd->prepare) if (fd->super.alive && fd->prepare)
PREPARE_FD(fd); PREPARE_FD(fd);
if (fd->close_now) if (!fd->super.alive)
{ {
if (fd->fd < 0) if (fd->fd < 0)
/* Unlink the file object, but don't close any underlying file. */ /* Unlink the file object, but don't close any underlying file. */
...@@ -176,7 +176,7 @@ int io_iter(struct io_backend *b) ...@@ -176,7 +176,7 @@ int io_iter(struct io_backend *b)
{ {
/* Do io. Note that the callback functions may add new fds to the /* Do io. Note that the callback functions may add new fds to the
* head of the list, or set the close_now flag on any fd. */ * head of the list, or clear the alive flag on any fd. */
struct lsh_fd *fd; struct lsh_fd *fd;
unsigned long i; unsigned long i;
...@@ -185,13 +185,13 @@ int io_iter(struct io_backend *b) ...@@ -185,13 +185,13 @@ int io_iter(struct io_backend *b)
{ {
assert(i<nfds); assert(i<nfds);
if (fd->close_now) if (!fd->super.alive)
continue; continue;
if (fds[i].revents & POLLOUT) if (fds[i].revents & POLLOUT)
WRITE_FD(fd); WRITE_FD(fd);
if (fd->close_now) if (!fd->super.alive)
continue; continue;
if (fds[i].revents & POLLIN) if (fds[i].revents & POLLIN)
...@@ -280,10 +280,9 @@ static void read_callback(struct lsh_fd *fd) ...@@ -280,10 +280,9 @@ static void read_callback(struct lsh_fd *fd)
{ {
if (self->buffer) if (self->buffer)
write_buffer_close(self->buffer); write_buffer_close(self->buffer);
fd->close_reason = LSH_FAILUREP(res) close_fd(fd,
? CLOSE_PROTOCOL_FAILURE : 0; LSH_FAILUREP(res) ? CLOSE_PROTOCOL_FAILURE : 0);
fd->close_now = 1;
} }
else if (res & LSH_CLOSE) else if (res & LSH_CLOSE)
{ {
...@@ -296,7 +295,7 @@ static void read_callback(struct lsh_fd *fd) ...@@ -296,7 +295,7 @@ static void read_callback(struct lsh_fd *fd)
self->handler = NULL; self->handler = NULL;
} }
else else
fd->close_now = 1; kill_fd(fd);
fd->close_reason fd->close_reason
= LSH_FAILUREP(res) ? CLOSE_PROTOCOL_FAILURE : CLOSE_EOF; = LSH_FAILUREP(res) ? CLOSE_PROTOCOL_FAILURE : CLOSE_EOF;
...@@ -326,14 +325,12 @@ static void write_callback(struct lsh_fd *fd) ...@@ -326,14 +325,12 @@ static void write_callback(struct lsh_fd *fd)
break; break;
case EPIPE: case EPIPE:
werror("Broken pipe\n"); werror("Broken pipe\n");
fd->close_reason = CLOSE_WRITE_FAILED; close_fd(fd, CLOSE_WRITE_FAILED);
fd->close_now = 1;
break; break;
default: default:
werror("io.c: write failed, %s\n", strerror(errno)); werror("io.c: write failed, %s\n", strerror(errno));
fd->close_reason = CLOSE_WRITE_FAILED; close_fd(fd, CLOSE_WRITE_FAILED);
fd->close_now = 1;
break; break;
} }
...@@ -363,9 +360,9 @@ static void listen_callback(struct lsh_fd *fd) ...@@ -363,9 +360,9 @@ static void listen_callback(struct lsh_fd *fd)
{ {
werror("Strange: Accepted a connection, " werror("Strange: Accepted a connection, "
"but failed before writing anything.\n"); "but failed before writing anything.\n");
fd->close_now = 1; close_fd(fd, (LSH_FAILUREP(res)
fd->close_reason = LSH_FAILUREP(res) ? CLOSE_PROTOCOL_FAILURE ? CLOSE_PROTOCOL_FAILURE
: CLOSE_EOF; : CLOSE_EOF));
} }
} }
...@@ -386,7 +383,7 @@ static void connect_callback(struct lsh_fd *fd) ...@@ -386,7 +383,7 @@ static void connect_callback(struct lsh_fd *fd)
/* To avoid actually closing the fd */ /* To avoid actually closing the fd */
fd->fd = -1; fd->fd = -1;
} }
fd->close_now = 1; kill_fd(fd);
} }
/* FIXME: Prehaps this function should return a suitable exit code? */ /* FIXME: Prehaps this function should return a suitable exit code? */
...@@ -414,6 +411,22 @@ void init_backend(struct io_backend *b) ...@@ -414,6 +411,22 @@ void init_backend(struct io_backend *b)
#endif #endif
} }
/* This function is called if a connection this file somehow dependent
* on disappears. For instance, the connection may have spawned a
* child process, and this file may be the stdin of that process. */
/* To kill a file, mark it for closing and the backend will do the work. */
static void do_kill_fd(struct resource *r)
{
CAST_SUBTYPE(lsh_fd, fd, r);
/* FIXME: It could make sense to you a separate close reason for
* killed files. For now, using the zero reason will supress calling
* of any close callbacks. */
if (r->alive)
close_fd(fd, 0);
}
/* Initializes a file structure, and adds it to the backend's list. */ /* Initializes a file structure, and adds it to the backend's list. */
static void init_file(struct io_backend *b, struct lsh_fd *f, int fd) static void init_file(struct io_backend *b, struct lsh_fd *f, int fd)
{ {
...@@ -430,7 +443,8 @@ static void init_file(struct io_backend *b, struct lsh_fd *f, int fd) ...@@ -430,7 +443,8 @@ static void init_file(struct io_backend *b, struct lsh_fd *f, int fd)
f->want_write = 0; f->want_write = 0;
f->write = NULL; f->write = NULL;
f->close_now = 0; f->super.alive = 1;
f->super.kill = do_kill_fd;
f->really_close = NULL; f->really_close = NULL;
f->next = b->files; f->next = b->files;
...@@ -635,7 +649,7 @@ static void prepare_write(struct lsh_fd *fd) ...@@ -635,7 +649,7 @@ static void prepare_write(struct lsh_fd *fd)
if (! (fd->want_write = write_buffer_pre_write(self->buffer)) if (! (fd->want_write = write_buffer_pre_write(self->buffer))
&& self->buffer->closed) && self->buffer->closed)
fd->close_now = 1; kill_fd(fd);
} }
struct abstract_write *io_read_write(struct io_backend *b, struct abstract_write *io_read_write(struct io_backend *b,
...@@ -717,12 +731,14 @@ struct io_fd *io_write(struct io_backend *b, ...@@ -717,12 +731,14 @@ struct io_fd *io_write(struct io_backend *b,
return f; return f;
} }
/* Marks a file for closing, at the end of the current iteration. void kill_fd(struct lsh_fd *fd)
* FIXME: Could be generalized for other fd:s than read-write fds. */ {
fd->super.alive = 0;
}
void close_fd(struct lsh_fd *fd, int reason) void close_fd(struct lsh_fd *fd, int reason)
{ {
debug("Marking fd %d for closing.\n", fd->fd); debug("Marking fd %d for closing.\n", fd->fd);
fd->close_reason = reason; fd->close_reason = reason;
fd->close_now = 1; kill_fd(fd);
} }
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define LSH_IO_H_INCLUDED #define LSH_IO_H_INCLUDED
#include "abstract_io.h" #include "abstract_io.h"
#include "resource.h"
#include "write_buffer.h" #include "write_buffer.h"
#include <time.h> #include <time.h>
...@@ -73,6 +74,7 @@ ...@@ -73,6 +74,7 @@
/* CLASS: /* CLASS:
(class (class
(name lsh_fd) (name lsh_fd)
(super resource)
(vars (vars
(next object lsh_fd) (next object lsh_fd)
(fd simple int) (fd simple int)
...@@ -92,7 +94,7 @@ ...@@ -92,7 +94,7 @@
; Called if poll indicates that data can be written. ; Called if poll indicates that data can be written.
(write method void) (write method void)
(close_now simple int) ; (close_now simple int)
(really_close method void))) (really_close method void)))
*/ */
...@@ -184,6 +186,9 @@ struct io_fd *io_write(struct io_backend *b, ...@@ -184,6 +186,9 @@ struct io_fd *io_write(struct io_backend *b,
UINT32 block_size, UINT32 block_size,
struct close_callback *close_callback); struct close_callback *close_callback);
/* Marks a file for close, without touching the close_Reason field. */
void kill_fd(struct lsh_fd *fd);
void close_fd(struct lsh_fd *fd, int reason); void close_fd(struct lsh_fd *fd, int reason);
......
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