Created
November 6, 2017 13:42
-
-
Save RutledgePaulV/9582d13e0924fb6da4892cdbde36e7ad to your computer and use it in GitHub Desktop.
Some macros for locking by value.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def ^:dynamic *locks* (atom {})) | |
(defn new-lock [] | |
{:count 1 :ref (Object.)}) | |
(defn inc-lock [lock] | |
(when lock (update lock :count inc))) | |
(defn dec-lock [lock] | |
(when lock (update lock :count dec))) | |
(defn obtain [v] | |
(get (swap! *locks* update v #(or (inc-lock %) (new-lock))) v)) | |
(defn release [v] | |
(swap! *locks* | |
(fn [value] | |
(when-some [entry (get value v)] | |
(if (= 1 (:count entry)) | |
(dissoc value v) | |
(assoc value v (dec-lock entry))))))) | |
(defmacro with-locks [locks & body] | |
`(binding [*locks* ~locks] ~@body)) | |
(defmacro with-own-locks [& body] | |
`(binding [*locks* (atom {})] ~@body)) | |
(defmacro on-value [value & body] | |
`(let [v# ~value] | |
(try (locking (:ref (obtain v#)) ~@body) | |
(finally (release v#))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment