X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/e8c92ba7b0a64a05806dc207b31c5c84b1edb16c..f6033c46c877646b95bc2e99ce69097203bc5c77:/server/server.c diff --git a/server/server.c b/server/server.c index 266c25b..1e4c6ca 100644 --- a/server/server.c +++ b/server/server.c @@ -1,6 +1,6 @@ /* * This file is part of DisOrder. - * Copyright (C) 2004, 2005, 2006 Richard Kettlewell + * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -115,10 +115,12 @@ static int writer_error(ev_source attribute((unused)) *ev, /* writer is done */ c->w = 0; if(c->r == 0) { - D(("server writer_error closes %d", fd)); + //D(("server writer_error closes %d", fd)); + info("server writer_error closes %d because all done", fd); /* TODO */ xclose(fd); /* reader is done too, close */ } else { - D(("server writer_error shutdown %d SHUT_WR", fd)); + //D(("server writer_error shutdown %d SHUT_WR", fd)); + info("server writer_error shutdown %d SHUT_WR", fd); /* TODO */ xshutdown(fd, SHUT_WR); /* reader is not done yet */ } } else { @@ -126,6 +128,7 @@ static int writer_error(ev_source attribute((unused)) *ev, error(errno_value, "S%x write error on socket", c->tag); if(c->r) ev_reader_cancel(c->r); + info("server writer_error closes %d because errno=%d", fd, errno_value); /* TODO */ xclose(fd); } return 0; @@ -139,7 +142,12 @@ static int reader_error(ev_source attribute((unused)) *ev, D(("server reader_error %d %d", fd, errno_value)); error(errno, "S%x read error on socket", c->tag); - ev_writer_cancel(c->w); + if(c->w) { + ev_writer_cancel(c->w); + c->w = 0; + } + ev_report(ev); + info("reader_error closing fd %d", fd); /* TODO */ xclose(fd); return 0; } @@ -663,21 +671,19 @@ static int c_random_enabled(struct conn *c, return 1; /* completed */ } +static void got_stats(char *stats, void *u) { + struct conn *const c = u; + + sink_printf(ev_writer_sink(c->w), "253 stats\n%s\n.\n", stats); + /* Now we can start processing commands again */ + ev_reader_enable(c->r); +} + static int c_stats(struct conn *c, char attribute((unused)) **vec, int attribute((unused)) nvec) { - char **v; - int nv, n; - - v = trackdb_stats(&nv); - sink_printf(ev_writer_sink(c->w), "253 stats\n"); - for(n = 0; n < nv; ++n) { - if(v[n][0] == '.') - sink_writes(ev_writer_sink(c->w), "."); - sink_printf(ev_writer_sink(c->w), "%s\n", v[n]); - } - sink_writes(ev_writer_sink(c->w), ".\n"); - return 1; + trackdb_stats_subprocess(c->ev, got_stats, c); + return 0; /* not yet complete */ } static int c_volume(struct conn *c, @@ -729,8 +735,11 @@ static int logging_reader_callback(ev_source *ev, /* don't log to this conn any more */ eventlog_remove(c->lo); - /* terminate the log output */ - sink_writes(ev_writer_sink(c->w), ".\n"); + if(c->w) { + /* Terminate the log output, but only if the writer hasn't been killed off + * from a failure on some earlier write */ + sink_writes(ev_writer_sink(c->w), ".\n"); + } /* restore the reader callback */ c->reader = reader_callback; /* ...and exit via it */ @@ -740,6 +749,11 @@ static int logging_reader_callback(ev_source *ev, static void logclient(const char *msg, void *user) { struct conn *c = user; + if(!c->w || !c->r) { + /* This connection has gone up in smoke for some reason */ + eventlog_remove(c->lo); + return; + } sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" %s\n", (uintmax_t)time(0), msg); }