From: Richard Kettlewell Date: Tue, 23 Oct 2007 22:19:41 +0000 (+0100) Subject: chattier event loop error logging X-Git-Tag: debian-1_5_99dev8~84 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/e8c92ba7b0a64a05806dc207b31c5c84b1edb16c chattier event loop error logging --- diff --git a/lib/event.c b/lib/event.c index 0cdcef2..487b9b2 100644 --- a/lib/event.c +++ b/lib/event.c @@ -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; } diff --git a/lib/event.h b/lib/event.h index 9f391fe..16a909f 100644 --- a/lib/event.h +++ b/lib/event.h @@ -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. */ diff --git a/lib/logfd.c b/lib/logfd.c index 29fd2ab..0eab833 100644 --- a/lib/logfd.c +++ b/lib/logfd.c @@ -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]; } diff --git a/server/play.c b/server/play.c index 1320e45..f0ac386 100644 --- a/server/play.c +++ b/server/play.c @@ -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) { diff --git a/server/server.c b/server/server.c index 80afbe5..266c25b 100644 --- a/server/server.c +++ b/server/server.c @@ -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; }