Skip to content

Instantly share code, notes, and snippets.

@llasram
Created July 18, 2012 11:56
Show Gist options
  • Save llasram/3135772 to your computer and use it in GitHub Desktop.
Save llasram/3135772 to your computer and use it in GitHub Desktop.
example.locks
(ns example.locks
(:import [clojure.lang IDeref IBlockingDeref]
[java.util.concurrent TimeUnit]
[java.util.concurrent.locks Lock ReadWriteLock
ReentrantReadWriteLock]))
(defmacro ^:private with-lock
([lock body]
`(try (.lock ~lock) ~@body (finally (.unlock ~lock))))
([lock timeout-ms timeout-val body]
`(if (.tryLock ~lock ~timeout-ms TimeUnit/MILLISECONDS)
(try ~@body (finally (.unlock ~lock)))
~timeout-val)))
(defmacro ^:private with-read-lock
[[rwlock & args] & body]
`(let [^ReadWriteLock rwlock# ~rwlock, lock# (.readLock rwlock#)]
(with-lock lock# ~@args ~body)))
(defmacro ^:private with-write-lock
[[rwlock & args] & body]
`(let [^ReadWriteLock rwlock# ~rwlock, lock# (.writeLock rwlock#)]
(with-lock lock# ~@args ~body)))
(defprotocol ILockedState
(locked-swap! [this f] [this f x] [this f x & args])
(locked-reset! [this newval]))
(deftype RWLockedState [^ReadWriteLock rwlock ^:unsynchronized-mutable value]
IDeref
(deref [_] (with-read-lock [rwlock] value))
IBlockingDeref
(deref [_ timeout-ms timeout-val]
(with-read-lock [rwlock timeout-ms timeout-val] value))
ILockedState
(locked-swap! [_ f]
(with-write-lock [rwlock] (set! value (f value))))
(locked-swap! [_ f x]
(with-write-lock [rwlock] (set! value (f value x))))
(locked-swap! [_ f x & args]
(with-write-lock [rwlock] (set! value (apply f value x args))))
(locked-reset! [_ newval]
(with-write-lock [rwlock] (set! value newval))))
(defn rw-locked-state
[x] (RWLockedState. (ReentrantReadWriteLock.) x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment