Serialize use of the process's current working directory.
The top-level REPL no longer munges the cwd. The only use of the
SET-WORKING-DIRECTORY-PATHNAME! primitive is serially, with a thread
mutex lock, in a dynamic-wind.
of@* @code{*default-pathname-defaults*} by merging the new working
directory into it.
-When this procedure is executed in the top-level @acronym{REP} loop, it
-changes the working directory of the running Scheme executable.
-
@example
@group
(set-working-directory-pathname! "/usr/morris/blisp")
console-i/o-port
user-initial-environment
#f
- `((SET-DEFAULT-DIRECTORY
- ,top-level-repl/set-default-directory))
+ '()
user-initial-prompt)
(cmdl-message/strings "Cold load finished")))))
(define root-continuation)
-
-(define (top-level-repl/set-default-directory cmdl pathname)
- cmdl
- ((ucode-primitive set-working-directory-pathname! 1)
- (->namestring pathname)))
\f
;;;; Command Loops
unix/current-uid
unix/gid->string
unix/system
- unix/uid->string)))
+ unix/uid->string)
+ (import (runtime thread)
+ allow-preempt-current-thread
+ disallow-preempt-current-thread)))
((nt)
(extend-package (runtime os-primitives)
(files "ntprm")
(system command-line)))
(define (system command-line)
- (let ((inside (->namestring
- (directory-pathname-as-file (working-directory-pathname))))
- (outside false))
+ (let ((inside (->namestring (working-directory-pathname)))
+ (preemptible? (thread-execution-state (current-thread)))
+ (outside))
(dynamic-wind
(lambda ()
- (stop-thread-timer)
+ (lock-thread-mutex cwd-mutex)
+ (set! preemptible? (not (eq? 'RUNNING-WITHOUT-PREEMPTION
+ (thread-execution-state (current-thread)))))
+ (disallow-preempt-current-thread)
(set! outside ((ucode-primitive working-directory-pathname 0)))
((ucode-primitive set-working-directory-pathname! 1) inside))
(lambda ()
((ucode-primitive system 1) command-line))
(lambda ()
- (set! inside ((ucode-primitive working-directory-pathname 0)))
((ucode-primitive set-working-directory-pathname! 1) outside)
- (start-thread-timer)))))
\ No newline at end of file
+ (set! outside)
+ (if preemptible?
+ (allow-preempt-current-thread))
+ (unlock-thread-mutex cwd-mutex)))))
\ No newline at end of file
(define (initialize-system-primitives!)
(set! environment-variables (make-string-hash-table))
+ (set! cwd-mutex (make-thread-mutex))
(add-event-receiver! event:after-restart reset-environment-variables!))
\f
;;;; MIME types
(or ((ucode-primitive gid->string 1) gid)
(number->string gid 10)))
+(define cwd-mutex)
+
(define (unix/system string)
- (let ((wd-inside (->namestring (working-directory-pathname)))
- (wd-outside)
- (ti-outside))
+ (let ((inside (->namestring (working-directory-pathname)))
+ (preemptible?)
+ (outside))
(dynamic-wind
(lambda ()
- (set! wd-outside ((ucode-primitive working-directory-pathname 0)))
- ((ucode-primitive set-working-directory-pathname! 1) wd-inside)
- (set! ti-outside (thread-timer-interval))
- (set-thread-timer-interval! #f))
+ (lock-thread-mutex cwd-mutex)
+ (set! preemptible? (not (eq? 'RUNNING-WITHOUT-PREEMPTION
+ (thread-execution-state (current-thread)))))
+ (disallow-preempt-current-thread)
+ (set! outside ((ucode-primitive working-directory-pathname 0)))
+ ((ucode-primitive set-working-directory-pathname! 1) inside))
(lambda ()
((ucode-primitive system 1) string))
(lambda ()
- ((ucode-primitive set-working-directory-pathname! 1) wd-outside)
- (set! wd-outside)
- (set-thread-timer-interval! ti-outside)
- (set! ti-outside)
- unspecific))))
+ ((ucode-primitive set-working-directory-pathname! 1) outside)
+ (set! outside)
+ (if preemptible?
+ (allow-preempt-current-thread))
+ (unlock-thread-mutex cwd-mutex)))))
\f
(define (file-line-ending pathname)
;; This works because the line translation is harmless when not