chiark / gitweb /
chattier event loop error logging
authorRichard Kettlewell <rjk@greenend.org.uk>
Tue, 23 Oct 2007 22:19:41 +0000 (23:19 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Tue, 23 Oct 2007 22:19:41 +0000 (23:19 +0100)
lib/event.c
lib/event.h
lib/logfd.c
server/play.c
server/server.c

index 0cdcef2..487b9b2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 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
@@ -55,6 +55,7 @@ struct fd {
   int fd;
   ev_fd_callback *callback;
   void *u;
+  const char *what;
 };
 
 struct fdmode {
@@ -130,6 +131,7 @@ int ev_run(ev_source *ev) {
     int ret;
     int maxfd;
     struct timeout *t, **tt;
+    struct stat sb;
 
     xgettimeofday(&now, 0);
     /* Handle timeouts.  We don't want to handle any timeouts that are added
@@ -188,6 +190,19 @@ int ev_run(ev_source *ev) {
     xsigprocmask(SIG_BLOCK, &ev->sigmask, 0);
     if(n < 0) {
       error(errno, "error calling select");
+      if(errno == EBADF) {
+       /* If there's a bad FD in the mix then check them all and log what we
+        * find, to ease debugging */
+       for(mode = 0; mode < ev_nmodes; ++mode) {
+         for(n = 0; n < ev->mode[mode].nfds; ++n) {
+           const int fd = ev->mode[mode].fds[n].fd;
+
+           if(FD_ISSET(fd, &ev->mode[mode].enabled)
+              && fstat(fd, &sb) < 0)
+             error(errno, "fstat %d (%s)", fd, ev->mode[mode].fds[n].what);
+         }
+       }
+      }
       return -1;
     }
     if(n > 0) {
@@ -219,7 +234,8 @@ int ev_fd(ev_source *ev,
          ev_fdmode mode,
          int fd,
          ev_fd_callback *callback,
-         void *u) {
+         void *u,
+         const char *what) {
   int n;
 
   D(("registering %s fd %d callback %p %p", modenames[mode], fd,
@@ -238,6 +254,7 @@ int ev_fd(ev_source *ev,
   ev->mode[mode].fds[n].fd = fd;
   ev->mode[mode].fds[n].callback = callback;
   ev->mode[mode].fds[n].u = u;
+  ev->mode[mode].fds[n].what = what;
   if(fd > ev->mode[mode].maxfd)
     ev->mode[mode].maxfd = fd;
   ev->escape = 1;
@@ -385,7 +402,7 @@ int ev_signal(ev_source *ev,
       nonblock(ev->sigpipe[n]);
       cloexec(ev->sigpipe[n]);
     }
-    if(ev_fd(ev, ev_read, ev->sigpipe[0], signal_read, 0)) {
+    if(ev_fd(ev, ev_read, ev->sigpipe[0], signal_read, 0, "sigpipe read")) {
       close_sigpipe(ev);
       return -1;
     }
@@ -575,13 +592,14 @@ static int listen_callback(ev_source *ev, int fd, void *u) {
 int ev_listen(ev_source *ev,
              int fd,
              ev_listen_callback *callback,
-             void *u) {
+             void *u,
+             const char *what) {
   struct listen_state *l = xmalloc(sizeof *l);
 
   D(("registering listener fd %d callback %p %p", fd, (void *)callback, u));
   l->callback = callback;
   l->u = u;
-  return ev_fd(ev, ev_read, fd, listen_callback, l);
+  return ev_fd(ev, ev_read, fd, listen_callback, l, what);
 }
 
 int ev_listen_cancel(ev_source *ev, int fd) {
@@ -680,7 +698,8 @@ static int ev_writer_write(struct sink *sk, const void *s, int n) {
 ev_writer *ev_writer_new(ev_source *ev,
                         int fd,
                         ev_error_callback *callback,
-                        void *u) {
+                        void *u,
+                        const char *what) {
   ev_writer *w = xmalloc(sizeof *w);
 
   D(("registering writer fd %d callback %p %p", fd, (void *)callback, u));
@@ -689,7 +708,7 @@ ev_writer *ev_writer_new(ev_source *ev,
   w->callback = callback;
   w->u = u;
   w->ev = ev;
-  if(ev_fd(ev, ev_write, fd, writer_callback, w))
+  if(ev_fd(ev, ev_write, fd, writer_callback, w, what))
     return 0;
   ev_fd_disable(ev, ev_write, fd);
   return w;
@@ -771,7 +790,8 @@ ev_reader *ev_reader_new(ev_source *ev,
                         int fd,
                         ev_reader_callback *callback,
                         ev_error_callback *error_callback,
-                        void *u) {
+                        void *u,
+                        const char *what) {
   ev_reader *r = xmalloc(sizeof *r);
 
   D(("registering reader fd %d callback %p %p %p",
@@ -781,7 +801,7 @@ ev_reader *ev_reader_new(ev_source *ev,
   r->error_callback = error_callback;
   r->u = u;
   r->ev = ev;
-  if(ev_fd(ev, ev_read, fd, reader_callback, r))
+  if(ev_fd(ev, ev_read, fd, reader_callback, r, what))
     return 0;
   return r;
 }
index 9f391fe..16a909f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004 Richard Kettlewell
+ * Copyright (C) 2004, 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
@@ -51,7 +51,8 @@ int ev_fd(ev_source *ev,
          ev_fdmode mode,
          int fd,
          ev_fd_callback *callback,
-         void *u);
+         void *u,
+         const char *what);
 /* register a callback on a file descriptor */
 
 int ev_fd_cancel(ev_source *ev,
@@ -146,7 +147,8 @@ typedef int ev_listen_callback(ev_source *ev,
 int ev_listen(ev_source *ev,
              int fd,
              ev_listen_callback *callback,
-             void *u);
+             void *u,
+             const char *what);
 /* register a socket listener callback.  @bind@ and @listen@ should
  * already have been called. */
 
@@ -168,7 +170,8 @@ typedef int ev_error_callback(ev_source *ev,
 ev_writer *ev_writer_new(ev_source *ev,
                         int fd,
                         ev_error_callback *callback,
-                        void *u);
+                        void *u,
+                        const char *what);
 /* create a new buffered writer, writing to @fd@.  Calls @error@ if an
  * error occurs. */
 
@@ -202,7 +205,8 @@ ev_reader *ev_reader_new(ev_source *ev,
                         int fd,
                         ev_reader_callback *callback,
                         ev_error_callback *error_callback,
-                        void *u);
+                        void *u,
+                        const char *what);
 /* register a new reader.  @callback@ will be called whenever data is
  * available. */
 
index 29fd2ab..0eab833 100644 (file)
@@ -80,7 +80,8 @@ int logfd(ev_source *ev, const char *tag) {
   xpipe(p);
   cloexec(p[0]);
   nonblock(p[0]);
-  if(!ev_reader_new(ev, p[0], logfd_readable, logfd_error, (void *)tag))
+  if(!ev_reader_new(ev, p[0], logfd_readable, logfd_error, (void *)tag,
+                    "logfd"))
     fatal(errno, "error calling ev_reader_new");
   return p[1];
 }
index 1320e45..f0ac386 100644 (file)
@@ -165,7 +165,7 @@ void speaker_setup(ev_source *ev) {
   /* Wait for the speaker to be ready */
   speaker_recv(speaker_fd, &sm);
   nonblock(speaker_fd);
-  ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0);
+  ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0, "speaker read");
 }
 
 void speaker_reload(void) {
index 80afbe5..266c25b 100644 (file)
@@ -1110,8 +1110,10 @@ static int listen_callback(ev_source *ev,
   cloexec(fd);
   c->tag = tags++;
   c->ev = ev;
-  c->w = ev_writer_new(ev, fd, writer_error, c);
-  c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c);
+  c->w = ev_writer_new(ev, fd, writer_error, c,
+                      "client writer");
+  c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c,
+                      "client reader");
   c->fd = fd;
   c->reader = reader_callback;
   c->l = l;
@@ -1147,7 +1149,8 @@ int server_start(ev_source *ev, int pf,
   cloexec(fd);
   l->name = name;
   l->pf = pf;
-  if(ev_listen(ev, fd, listen_callback, l)) exit(EXIT_FAILURE);
+  if(ev_listen(ev, fd, listen_callback, l, "server listener"))
+    exit(EXIT_FAILURE);
   return fd;
 }