Avoiding a race condition in synchronized-rewrite-file.

This commit is contained in:
Alex Shinn 2015-05-02 22:35:51 +09:00
parent 0df0dc3e2b
commit c7d64a19c4

View file

@ -126,22 +126,21 @@
(define (file-lock-loop port-or-fd mode)
(let lp ()
(let ((res (file-lock port-or-fd mode)))
(cond
(res)
((file-lock port-or-fd mode))
((memv (errno) '(11 35)) (thread-sleep! 0.01) (lp))
(else (error "couldn't lock file" (integer->error-string)))))))
(else (error "couldn't lock file" (integer->error-string))))))
(define (call-with-locked-file path proc . o)
(let ((fd (open path open/read-write (if (pair? o) (car o) #o644))))
(let ((fd (open path
(+ open/create open/read-write)
(if (pair? o) (car o) #o644))))
(file-lock-loop fd (+ lock/exclusive lock/non-blocking))
(exception-protect (proc fd) (file-lock fd lock/unlock))))
;; Rewrites file in place with the result of (proc orig-contents),
;; synchronized with file-lock.
(define (synchronized-rewrite-text-file path proc . o)
(cond
((file-exists? path)
(call-with-locked-file
path
(lambda (fd)
@ -153,9 +152,6 @@
(file-truncate out (string-size res))
(close-output-port out)
res))))
(else
(call-with-output-file path
(lambda (out) (display (proc (if (pair? o) (car o) "")) out))))))
(define (synchronized-rewrite-sexp-file path proc . o)
(apply synchronized-rewrite-text-file