chiark / gitweb /
avoid crashes on log client teardown
[disorder] / server / server.c
index a112f78dba02dfc76ba076b369be5ddac9e570c6..1e4c6ca91930f9d8b1d4ac40849e7926828f236e 100644 (file)
@@ -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,9 +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("closing fd %d", fd);
+  info("reader_error closing fd %d", fd); /* TODO */
   xclose(fd);
   return 0;
 }
@@ -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);
 }