This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-20
Channels
- # announcements (7)
- # babashka (16)
- # beginners (58)
- # boot (12)
- # calva (3)
- # cider (11)
- # clj-kondo (9)
- # cljs-dev (8)
- # clojure (82)
- # clojure-europe (9)
- # clojure-italy (11)
- # clojure-losangeles (1)
- # clojure-nl (8)
- # clojure-uk (8)
- # clojurescript (5)
- # css (2)
- # cursive (5)
- # datomic (20)
- # docker (2)
- # emacs (4)
- # figwheel-main (16)
- # fulcro (53)
- # graalvm (17)
- # jackdaw (2)
- # jobs (4)
- # kaocha (6)
- # lambdaisland (2)
- # luminus (2)
- # meander (1)
- # off-topic (146)
- # re-frame (4)
- # releases (1)
- # rum (12)
- # sci (71)
- # shadow-cljs (26)
- # test-check (22)
- # vim (1)
- # xtdb (9)
I'm getting the locking issue while compiling a library (datalevin) with GraalVM native-image. Haven't dug deeply into this yet. Could be that some AOT-ed thing is left on the classpath that brings in the old locking stuff, but the source which occurs in the error output is not AOT-ed I believe: https://github.com/borkdude/datalevin-native
Hmm, I believe this repros it:
(defprotocol IFoo
(store [_]))
(deftype Foo [^:volatile-mutable ^long max-gt]
IFoo
(store [_]
(locking max-gt
(println "Stored!"))))
(defn -main [& _args]
(let [foo (Foo. 10)]
(store foo))
Error: unbalanced monitors: mismatch at monitorexit, 7|Invoke#Numbers.num != 52|Invoke#Numbers.num
Detailed message:
Call path from entry point to borkdude.datalevin_native.main.Foo.store():
at borkdude.datalevin_native.main.Foo.store(main.clj:14)
I'll make a dedicated repro repo in a few hours, and I'll add some comment to CLJ-1472 (cc @alexmiller)
Aha!
When I remove the ^long
type hint, then it compiles:
(defprotocol IFoo
(store [_]))
(deftype Foo [^long max-gt]
IFoo
(store [_]
(locking max-gt
(println "Stored!"))))
(defn -main [& _args]
(let [foo (Foo. 10)]
(store foo)))
just file a new ticket
and link to CLJ-1472
wait, you can't lock on a primitive long - it has to be an object
that code doesn't make sense
yeah, I figured the same. it comes from here: https://github.com/juji-io/datalevin/blob/0588dde496b18ced06fed036db3f969c35c69ef8/src/datalevin/storage.clj#L226
yeah, that's bad
my guess would be that in some cases the primitive long is getting up cast. that's the only way it could work (but locking on a Long value is still a bad idea). this code is just wrong.
the Java numeric value objects can be cached around 0 and that means the scope of your Long sharing can escape your own code (similarly, you should never lock on a String instance which might be interned)
it's best to make an explicit lock Object