Skip to content

Instantly share code, notes, and snippets.

@mfikes
Last active June 9, 2018 16:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfikes/9ef1908fff34c52a624f3dcf408d545f to your computer and use it in GitHub Desktop.
Save mfikes/9ef1908fff34c52a624f3dcf408d545f to your computer and use it in GitHub Desktop.
clj -m cljs.main -re nashorn
(def thread (.type js/Java "java.lang.Thread"))

(let [global-atom-lock
      (let [ctor (.type js/Java "java.util.concurrent.locks.ReentrantLock")]
        (new ctor))]
  (defn swap!
    [a f & args]
    (loop [old-val @a]
      (let [new-val (apply f old-val args)]
        (.lock global-atom-lock)
        (if (= @a old-val)
          (do
            (cljs.core/reset! a new-val)
            (.unlock global-atom-lock)
            new-val)
          (do
            (.unlock global-atom-lock)
            (recur @a))))))

  (defn reset! [a new-value]
    (.lock global-atom-lock)
    (cljs.core/reset! a new-value)
    (.unlock global-atom-lock)
    new-value))

(def initial-value {:v 0
                    :a {:v 0
                        :b {:v 0
                            :c {:v 0
                                :d {:v 0
                                    :e {:v 0
                                        :f {:v 0}}}}}}})
(def x (atom initial-value))

(defn worker []
  (swap! x update-in (concat (take (rand-int 7) [:a :b :c :d :e :f]) [:v]) inc)
  (.sleep thread 10)
  (recur))

(dotimes [_ 100]
  (.start (new thread worker)))

Then try evaluating @x to see if it rips itself apart. You should see values like

{:v 282904, :a {:v 280910, :b {:v 282212, :c {:v 281561, :d {:v 282548, :e {:v 282555, :f {:v 282178}}}}}}}

You can also do this:

(swap! x update-in (concat (take (rand-int 7) [:a :b :c :d :e :f]) [:v]) inc)

You can also

(reset! x initial-value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment