added user-directory lock
svn: r796
This commit is contained in:
parent
1dbff144c2
commit
39a44d0849
|
@ -7,6 +7,7 @@
|
||||||
(lib "date.ss")
|
(lib "date.ss")
|
||||||
(lib "list.ss")
|
(lib "list.ss")
|
||||||
"md5.ss"
|
"md5.ss"
|
||||||
|
"lock.ss"
|
||||||
"web-status-server.ss"
|
"web-status-server.ss"
|
||||||
"run-status.ss")
|
"run-status.ss")
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(define ATTEMPT-DIR "ATTEMPT")
|
(define ATTEMPT-DIR "ATTEMPT")
|
||||||
|
|
||||||
(define (success-dir n)
|
(define (success-dir n)
|
||||||
(format "SUCCESS-~a" n))
|
(format "SUCCESS-~a" n))
|
||||||
(define (make-success-dir-available n)
|
(define (make-success-dir-available n)
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
(parameterize ([current-directory (build-path "active" assignment)])
|
(parameterize ([current-directory (build-path "active" assignment)])
|
||||||
(unless (directory-exists? user)
|
(unless (directory-exists? user)
|
||||||
(make-directory user))
|
(make-directory user))
|
||||||
|
(wait-for-lock user)
|
||||||
(parameterize ([current-directory user])
|
(parameterize ([current-directory user])
|
||||||
(let ([len (read r-safe)])
|
(let ([len (read r-safe)])
|
||||||
(unless (and (number? len)
|
(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