added user-directory lock
svn: r796
This commit is contained in:
parent
1dbff144c2
commit
39a44d0849
|
@ -7,6 +7,7 @@
|
|||
(lib "date.ss")
|
||||
(lib "list.ss")
|
||||
"md5.ss"
|
||||
"lock.ss"
|
||||
"web-status-server.ss"
|
||||
"run-status.ss")
|
||||
|
||||
|
@ -63,6 +64,7 @@
|
|||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define ATTEMPT-DIR "ATTEMPT")
|
||||
|
||||
(define (success-dir n)
|
||||
(format "SUCCESS-~a" n))
|
||||
(define (make-success-dir-available n)
|
||||
|
@ -82,6 +84,7 @@
|
|||
(parameterize ([current-directory (build-path "active" assignment)])
|
||||
(unless (directory-exists? user)
|
||||
(make-directory user))
|
||||
(wait-for-lock user)
|
||||
(parameterize ([current-directory user])
|
||||
(let ([len (read r-safe)])
|
||||
(unless (and (number? len)
|
||||
|
|
60
collects/handin-server/lock.ss
Normal file
60
collects/handin-server/lock.ss
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
(module lock mzscheme
|
||||
(require (lib "list.ss"))
|
||||
|
||||
(provide wait-for-lock)
|
||||
|
||||
;; wait-for-lock : string -> void
|
||||
;; Gets a lock on `user' for the calling thread; the lock
|
||||
;; lasts until the calling thread terminates.
|
||||
(define (wait-for-lock user)
|
||||
(let ([s (make-semaphore)])
|
||||
(channel-put req-ch (make-req
|
||||
(thread-dead-evt (current-thread))
|
||||
user
|
||||
s))
|
||||
(semaphore-wait s)))
|
||||
|
||||
(define req-ch (make-channel))
|
||||
|
||||
(define-struct req (thread-dead-evt
|
||||
user
|
||||
sema))
|
||||
|
||||
(thread (lambda ()
|
||||
(let loop ([locks null]
|
||||
[reqs null])
|
||||
(let-values ([(locks reqs)
|
||||
;; Try to satisfy lock requests:
|
||||
(let loop ([reqs (reverse reqs)][locks locks][new-reqs null])
|
||||
(cond
|
||||
[(null? reqs) (values locks new-reqs)]
|
||||
[(assoc (req-user (car reqs)) locks)
|
||||
;; Lock not available:
|
||||
(loop (cdr reqs) locks (cons (car reqs) new-reqs))]
|
||||
[else
|
||||
;; Lock is available, so take it:
|
||||
(let ([req (car reqs)])
|
||||
(semaphore-post (req-sema req))
|
||||
(loop (cdr reqs) (cons (cons (req-user req) req) locks) new-reqs))]))])
|
||||
(sync
|
||||
(handle-evt
|
||||
req-ch
|
||||
(lambda (req)
|
||||
(loop locks (cons req reqs))))
|
||||
;; Release a lock whose thread is gone:
|
||||
(apply choice-evt
|
||||
(map (lambda (name+req)
|
||||
(handle-evt
|
||||
(req-thread-dead-evt (cdr name+req))
|
||||
(lambda (v)
|
||||
(loop (remq name+req locks) reqs))))
|
||||
locks))
|
||||
;; Throw away a request whose thread is gone:
|
||||
(apply choice-evt
|
||||
(map (lambda (req)
|
||||
(handle-evt
|
||||
(req-thread-dead-evt req)
|
||||
(lambda (v)
|
||||
(loop locks (remq req reqs)))))
|
||||
reqs))))))))
|
Loading…
Reference in New Issue
Block a user