Skip site navigation (1)Skip section navigation (2)
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>