Use make-preserved-thread-fluid for the process resources.
Fixed indentation.
This commit is contained in:
		
							parent
							
								
									8bba3a13e1
								
							
						
					
					
						commit
						3620d702f0
					
				
							
								
								
									
										151
									
								
								scsh/scsh.scm
								
								
								
								
							
							
						
						
									
										151
									
								
								scsh/scsh.scm
								
								
								
								
							| 
						 | 
					@ -142,97 +142,98 @@
 | 
				
			||||||
;;; (thread-set-resource ('X -> unspec))
 | 
					;;; (thread-set-resource ('X -> unspec))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-syntax  make-process-resource
 | 
					(define-syntax  make-process-resource
 | 
				
			||||||
  (syntax-rules ()
 | 
					  (syntax-rules 
 | 
				
			||||||
    ((make-process-resource 
 | 
					   ()
 | 
				
			||||||
      initialize-resource 
 | 
					   ((make-process-resource 
 | 
				
			||||||
      thread-read-resource thread-set-resource! thread-change-resource 
 | 
					     initialize-resource 
 | 
				
			||||||
      with-resource* with-resource-aligned* 
 | 
					     thread-read-resource thread-set-resource! thread-change-resource 
 | 
				
			||||||
      process-read-resource process-set-resource resource-eq?)
 | 
					     with-resource* with-resource-aligned* 
 | 
				
			||||||
(begin 
 | 
					     process-read-resource process-set-resource resource-eq?)
 | 
				
			||||||
(define *resource-cache* 'uninitialized)
 | 
					    (begin 
 | 
				
			||||||
(define resource-lock 'uninitialized)
 | 
					      (define *resource-cache* 'uninitialized)
 | 
				
			||||||
 | 
					      (define resource-lock 'uninitialized)
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
(define (initialize-resource)
 | 
					      (define (initialize-resource)
 | 
				
			||||||
  (set! *resource-cache* (process-read-resource))
 | 
						(set! *resource-cache* (process-read-resource))
 | 
				
			||||||
  (set! $resource ;;; TODO The old thread-fluid will remain
 | 
						(set! $resource ;;; TODO The old thread-fluid will remain
 | 
				
			||||||
  (make-thread-fluid
 | 
						      (make-preserved-thread-fluid
 | 
				
			||||||
   (process-read-resource)))
 | 
						       (process-read-resource)))
 | 
				
			||||||
  (set! resource-lock (make-lock)))
 | 
						(set! resource-lock (make-lock)))
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
(define (cache-value)
 | 
					      (define (cache-value)
 | 
				
			||||||
  *resource-cache*)
 | 
						*resource-cache*)
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
;;; Actually do the syscall and update the cache
 | 
					      ;; Actually do the syscall and update the cache
 | 
				
			||||||
;;; assumes the resource lock obtained
 | 
					      ;; assumes the resource lock obtained
 | 
				
			||||||
(define (change-and-cache dir)
 | 
					      (define (change-and-cache dir)
 | 
				
			||||||
  (process-set-resource dir)
 | 
						(process-set-resource dir)
 | 
				
			||||||
  (set! *resource-cache* (process-read-resource)))
 | 
						(set! *resource-cache* (process-read-resource)))
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
;;; Dynamic-wind is not the right thing to take care of the lock;
 | 
					      ;; Dynamic-wind is not the right thing to take care of the lock;
 | 
				
			||||||
;;; it would release the lock on every context switch.
 | 
					      ;; it would release the lock on every context switch.
 | 
				
			||||||
;;; With-lock releases the lock on a condition, using call/cc will 
 | 
					      ;; With-lock releases the lock on a condition, using call/cc will 
 | 
				
			||||||
;;; skrew things up
 | 
					      ;; skrew things up
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
;;; The thread-specific resource: A thread fluid
 | 
					      ;; The thread-specific resource: A thread fluid
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
(define $resource 'empty-resource-value)
 | 
					      (define $resource 'empty-resource-value)
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
(define (thread-read-resource) (thread-fluid $resource))
 | 
					      (define (thread-read-resource) (thread-fluid $resource))
 | 
				
			||||||
(define (thread-set-resource! dir) (set-thread-fluid! $resource dir))
 | 
					      (define (thread-set-resource! dir) (set-thread-fluid! $resource dir))
 | 
				
			||||||
(define (let-resource dir thunk)
 | 
					      (define (let-resource dir thunk)
 | 
				
			||||||
  (let-thread-fluid $resource dir thunk))
 | 
						(let-thread-fluid $resource dir thunk))
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
(define (with-resource* dir thunk) 
 | 
					      (define (with-resource* dir thunk) 
 | 
				
			||||||
  (let ((changed-dir #f))  ; TODO 0.5 used to have a dynamic-wind here!!!
 | 
						(let ((changed-dir #f))		; TODO 0.5 used to have a dynamic-wind here!!!
 | 
				
			||||||
    (with-lock resource-lock
 | 
						  (with-lock resource-lock
 | 
				
			||||||
	       (lambda ()
 | 
							     (lambda ()
 | 
				
			||||||
		 (change-and-cache dir)
 | 
							       (change-and-cache dir)
 | 
				
			||||||
		 (set! changed-dir (cache-value))))
 | 
							       (set! changed-dir (cache-value))))
 | 
				
			||||||
    (let-resource changed-dir thunk)))
 | 
						  (let-resource changed-dir thunk)))
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
;; Align the value of the Unix resource with scsh's value.
 | 
					      ;; Align the value of the Unix resource with scsh's value.
 | 
				
			||||||
;; Since another thread could disalign, this call and
 | 
					      ;; Since another thread could disalign, this call and
 | 
				
			||||||
;; any ensuring syscall that relies upon it should
 | 
					      ;; any ensuring syscall that relies upon it should
 | 
				
			||||||
;; be "glued together" with the resource lock.
 | 
					      ;; be "glued together" with the resource lock.
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
(define (align-resource!)
 | 
					      (define (align-resource!)
 | 
				
			||||||
  (let ((dir (thread-read-resource)))
 | 
						(let ((dir (thread-read-resource)))
 | 
				
			||||||
    (if (not (resource-eq? dir (cache-value)))
 | 
						  (if (not (resource-eq? dir (cache-value)))
 | 
				
			||||||
	(change-and-cache dir))))
 | 
						      (change-and-cache dir))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (thread-change-resource dir)
 | 
					      (define (thread-change-resource dir)
 | 
				
			||||||
  (with-lock resource-lock
 | 
						(with-lock resource-lock
 | 
				
			||||||
	     (lambda ()
 | 
							   (lambda ()
 | 
				
			||||||
	       (align-resource!)
 | 
							     (align-resource!)
 | 
				
			||||||
	       (change-and-cache dir)
 | 
							     (change-and-cache dir)
 | 
				
			||||||
	       (thread-set-resource! (cache-value)))))
 | 
							     (thread-set-resource! (cache-value)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;; For thunks that don't raise exceptions or throw to continuations,
 | 
					      ;; For thunks that don't raise exceptions or throw to continuations,
 | 
				
			||||||
;;; this is overkill & probably a little heavyweight for frequent use.
 | 
					      ;; this is overkill & probably a little heavyweight for frequent use.
 | 
				
			||||||
;;; But it is general.
 | 
					      ;; But it is general.
 | 
				
			||||||
;;;
 | 
					      ;;
 | 
				
			||||||
;;; A less-general, more lightweight hack could be done just for
 | 
					      ;; A less-general, more lightweight hack could be done just for
 | 
				
			||||||
;;; syscalls.  We could probably dump the DYNAMIC-WINDs and build the
 | 
					      ;; syscalls.  We could probably dump the DYNAMIC-WINDs and build the
 | 
				
			||||||
;;; rest of the pattern into one of the syscall-defining macros, or
 | 
					      ;; rest of the pattern into one of the syscall-defining macros, or
 | 
				
			||||||
;;; something.  
 | 
					      ;; something.  
 | 
				
			||||||
;;; Olin adds the following: the efficient way to do things is not
 | 
					      ;; Olin adds the following: the efficient way to do things is not
 | 
				
			||||||
;;; with a dynamic wind or a lock. Just turn off interrupts, sync the
 | 
					      ;; with a dynamic wind or a lock. Just turn off interrupts, sync the
 | 
				
			||||||
;;; resource, do the syscall, turn them back on.
 | 
					      ;; resource, do the syscall, turn them back on.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (with-resource-aligned* thunk)
 | 
					      (define (with-resource-aligned* thunk)
 | 
				
			||||||
  (dynamic-wind (lambda ()
 | 
						(dynamic-wind (lambda ()
 | 
				
			||||||
		  (with-lock resource-lock
 | 
								(with-lock resource-lock
 | 
				
			||||||
			     align-resource!)) 
 | 
									   align-resource!)) 
 | 
				
			||||||
		thunk 
 | 
							      thunk 
 | 
				
			||||||
		values))
 | 
							      values))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;; example syscall
 | 
					      ;; example syscall
 | 
				
			||||||
;;; (define (exported-delete-file fname)
 | 
					      ;; (define (exported-delete-file fname)
 | 
				
			||||||
;;;;  (with-cwd-aligned (really-delete-file fname)))
 | 
					      ;;  (with-cwd-aligned (really-delete-file fname)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define resource-reinitializer
 | 
					      (define resource-reinitializer
 | 
				
			||||||
  (make-reinitializer (lambda () (warn "calling resumer") (initialize-resource))))))))
 | 
						(make-reinitializer (lambda () (warn "calling resumer") (initialize-resource))))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
;;; working directory per thread
 | 
					;;; working directory per thread
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue