Subject: Re: 23.0.92; Bug in Directory Variables

From: Stefan Monnier <[email-masked]>
Date: Thu, 09 Apr 2009 10:27:22 -0400

> The following patch changes the directory local variables code so that
> the cache stores the file atime.  Before using each cache entry, we
> check that against the file modtime.

I'm not sure this is the right thing to do:
- We don't know that the (float-time) is in sync with the filesystem's
  time, so the check may not work right.  Better check the file's
  current mtime against the file's mtime when it was last read.
- the variable you changed could previously be setq in the .emacs,
  whereas you changed it into an internal var.

FWIW, here's the patch I was working on instead.

        Stefan

--- files.el.~1.1044.~	2009-04-08 20:09:55.000000000 -0400
+++ files.el	2009-04-09 10:24:53.000000000 -0400
@@ -3314,21 +3314,31 @@
 	  dir-elt)
       (or locals-file dir-elt))))
 
+(defvar dir-locals--file-cache nil
+  "Cache of dir-locals files's contents.")
+
 (defun dir-locals-read-from-file (file)
   "Load a variables FILE and register a new class and instance.
 FILE is the name of the file holding the variables to apply.
 The new class name is the same as the directory in which FILE
 is found.  Returns the new class name."
+  (let ((mtime (nth 5 (file-attributes file)))
+        (cache (assoc file dir-locals--file-cache)))
+    (unless (equal (nth 1 cache) mtime)
+      (setq dir-locals--file-cache (delq cache dir-locals--file-cache))
+      (setq cache nil))
+    (if cache
+        (nth 2 cache)
+      (let ((val
   (with-temp-buffer
-    ;; We should probably store the modtime of FILE and then
-    ;; reload it whenever it changes.
     (insert-file-contents file)
     (let* ((dir-name (file-name-directory file))
 	   (class-name (intern dir-name))
 	   (variables (read (current-buffer))))
       (dir-locals-set-class-variables class-name variables)
-      (dir-locals-set-directory-class dir-name class-name)
-      class-name)))
+                 class-name))))
+        (push (list file mtime val) dir-locals--file-cache)
+        val))))
 
 (declare-function c-postprocess-file-styles "cc-mode" ())