Skip to content

Instantly share code, notes, and snippets.

@RutledgePaulV
Created November 6, 2017 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RutledgePaulV/9582d13e0924fb6da4892cdbde36e7ad to your computer and use it in GitHub Desktop.
Save RutledgePaulV/9582d13e0924fb6da4892cdbde36e7ad to your computer and use it in GitHub Desktop.
Some macros for locking by value.
(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