Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#44 Recursive file load loop if asdf file is in the future

open
Daniel Barlow
asdf (12)
5
2006-09-11
2006-09-11
Liam Healy
No

If the .asd file has a timestamp in the future, due
e.g. to clock disparity between file server and
desktop, ASDF gets in an infinite recursion of file
loads on this file; see sample at
http://paste.lisp.org/display/25828. Perhaps clock
skew could be detected and reported, as make does?

Discussion

  • Kambiz Darabi
    Kambiz Darabi
    2008-09-29

    During the first call to find-system, the asd file is loaded which leads to defsystem setting the car of the hash table entry in *defined-systems* to the current time:

    (setf (car s) (get-universal-time)))

    later, during the same call, find-system is called again which compares the car of the *defined-systems* entry to the file-write-date:

    (< (car in-memory) (file-write-date on-disk))))

    This test fails, if the file-write-date is in the future.

    One way to fix this problem might be to keep the file-write-date of the system for which find-system is being called in a var and use that file-write-date instead of get-universal-time.

    Here is the (probably horrible) patch just to illustrate the issue:

    Index: asdf.lisp

    RCS file: /cvsroot/cclan/asdf/asdf.lisp,v
    retrieving revision 1.128
    diff -r1.128 asdf.lisp
    369a370,374
    > (defvar *found-system* (list nil 0)
    > "A two element list which holds the coerce-name and file-write-date
    > of the current system during a find-system call to prevent recursive
    > calls to find-system")
    >
    420c425,426
    < (let ((*package* package))
    ---
    > (let ((*package* package)
    > (*found-system* (list name (file-write-date on-disk))))
    429c435,436
    < (delete-package package))))
    ---
    > (delete-package package)
    > (setf *found-system* (list nil 0)))))
    436c443
    < (defun register-system (name system)
    ---
    > (defun asdf::register-system (name system)
    438,439c445,452
    < (setf (gethash (coerce-name name) *defined-systems*)
    < (cons (get-universal-time) system)))
    ---
    > (let ((name (coerce-name name)))
    > (setf (gethash name *defined-systems*)
    > (cons (on-disk-or-universal-time name) system))))
    >
    > (defun on-disk-or-universal-time (name)
    > (if (equal (coerce-name name) (car *found-system*))
    > (second *found-system*)
    > (get-universal-time)))
    1106c1119
    < (setf (car s) (get-universal-time)))
    ---
    > (setf (car s) (on-disk-or-universal-time ',name)))

     
  • Kambiz Darabi
    Kambiz Darabi
    2008-09-29

    Oops. I wrote

    This test fails, if the file-write-date is in the future.

    The correct sentence would have been:

    This test always succeeds, if the file-write-date is in the future, so (load on-disk) is attempted again.