svn commit: r196011 - projects/jbuild/usr.bin/jbuild/filemon
John Birrell
jb at FreeBSD.org
Sat Aug 1 07:42:40 UTC 2009
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;
More information about the svn-src-projects
mailing list