I am writing a script that runs in many processes, but only one process at a time may access an external resource. The external resource is identified by a unique string (called the slug (an old newspaper term for a story's unique id)).
I am storing the list of "locked" slugs in a shared page, and trying to control access to that page with semaphores. I wrote a macro to automate this:
Code: Select all
(constant 'wait -1 'sig 1 'release 0)
(setq locked (share))
(share locked "")
(setq sid (semaphore))
(semaphore sid sig)
(define-macro (with-locked-slug)
(letex ((slug (eval (first (args)))) (body (cons 'begin (rest (args)))))
(let ((current (list slug)) (result nil))
;; block until slug is out of currently locked slugs list
(while (member slug current)
(semaphore sid wait)
(setq current (parse (share locked)))
(semaphore sid sig))
;; lock slug
(semaphore sid wait)
(share locked (string (share locked) " " slug))
(semaphore sid sig)
;; evaluate body
(setq result body)
;; unlock slug
(semaphore sid wait)
(setq current (parse (share locked)))
(pop current (find slug current))
(share locked (join current " "))
(semaphore sid sig)
;; return result of evaluation
result)))
I am not particularly experienced at low-level ipc stuff. Does anyone see a problem with this code? Anyone have any suggestions for making it more efficient?