Date: Sat, 1 Aug 2009 07:42:39 +0000 (UTC) From: John Birrell <jb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r196011 - projects/jbuild/usr.bin/jbuild/filemon Message-ID: <200908010742.n717gdpb095282@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jb Date: Sat Aug 1 07:42:39 2009 New Revision: 196011 URL: http://svn.freebsd.org/changeset/base/196011 Log: Keep filemon structs in a free list and reuse them. There is currently a race condition that allows a filemon struct to be freed when the filemon fd is closed, but while there is still a syscall active via the fd. Modified: projects/jbuild/usr.bin/jbuild/filemon/filemon.c Modified: projects/jbuild/usr.bin/jbuild/filemon/filemon.c ============================================================================== --- projects/jbuild/usr.bin/jbuild/filemon/filemon.c Sat Aug 1 07:09:50 2009 (r196010) +++ projects/jbuild/usr.bin/jbuild/filemon/filemon.c Sat Aug 1 07:42:39 2009 (r196011) @@ -69,6 +69,7 @@ struct filemon { }; static TAILQ_HEAD(, filemon) filemons_inuse = TAILQ_HEAD_INITIALIZER(filemons_inuse); +static TAILQ_HEAD(, filemon) filemons_free = TAILQ_HEAD_INITIALIZER(filemons_free); static int n_readers = 0; static struct mtx access_mtx; static struct cv access_cv; @@ -122,22 +123,32 @@ filemon_dtr(void *data) struct filemon *filemon = data; if (filemon != NULL) { + struct file *fp = filemon->fp; + /* Get exclusive write access. */ filemon_lock_write(); /* Remove from the in-use list. */ TAILQ_REMOVE(&filemons_inuse, filemon, link); + filemon->fp = NULL; + filemon->pid = -1; + + /* Add to the free list. */ + TAILQ_INSERT_TAIL(&filemons_free, filemon, link); + /* Give up write access. */ filemon_unlock_write(); - if (filemon->fp != NULL) - fdrop(filemon->fp, curthread); + if (fp != NULL) + fdrop(fp, curthread); +#ifdef DOODAD mtx_destroy(&filemon->mtx); cv_destroy(&filemon->cv); free(filemon, M_FILEMON); +#endif } } @@ -181,13 +192,25 @@ filemon_open(struct cdev *dev, int oflag { struct filemon *filemon; - filemon = malloc(sizeof(struct filemon), M_FILEMON, M_WAITOK | M_ZERO); + /* Get exclusive write access. */ + filemon_lock_write(); - filemon->pid = curproc->p_pid; - filemon->fp = NULL; + if ((filemon = TAILQ_FIRST(&filemons_free)) != NULL) + TAILQ_REMOVE(&filemons_free, filemon, link); - mtx_init(&filemon->mtx, "filemon", "filemon", MTX_DEF); - cv_init(&filemon->cv, "filemon"); + /* Give up write access. */ + filemon_unlock_write(); + + if (filemon == NULL) { + filemon = malloc(sizeof(struct filemon), M_FILEMON, M_WAITOK | M_ZERO); + + filemon->fp = NULL; + + mtx_init(&filemon->mtx, "filemon", "filemon", MTX_DEF); + cv_init(&filemon->cv, "filemon"); + } + + filemon->pid = curproc->p_pid; #if __FreeBSD_version < 701000 dev->si_drv1 = filemon;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908010742.n717gdpb095282>