2024 Clojure状态调查! 中分享你的看法。

欢迎!请参阅关于页面以了解更多有关它的工作方式的信息。

0
Clojure
即使对于当前线程未绑定的 thread-local 绑定,{{thread-bound?}} 也返回 true。这与文档字符串相矛盾,它指出如果返回 true,{{set!}} 应该成功。

以下是一个示例 REPL 会话,其中线程建立了一个绑定,这些绑定传达给第二个线程,第二个线程检查 thread-bound? 以查看是否可以设置该绑定,thread-bound? 返回 true 指示可以设置绑定,第二个线程试图设置绑定,并且第二个线程收到一个 IllegalStateException


    Clojure 1.5.1
    user=> (def ^:dynamic *set-me* nil)
    #'user/*set-me*
    user=> (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? #'*set-me*) (set! *set-me* (inc *set-me*)))))))
    #'user/try-to-set
    user=> (try-to-set)
    IllegalStateException 无法设置:*set-me* 来自非绑定线程 clojure.lang.Var.set (Var.java:230)
    user=>


方案:当存在绑定并且该绑定不是由当前线程建立的情况下,thread-bound? 应该返回 false。此补丁通过向 Var 添加新函数来实现了,因为核心库无法看到非公共 Var$TBox。

补丁:thread-bound.diff

审核人员:Alex Miller

4 答案

0

评论者:pjstadig

我附上一个补丁,该补丁将 clojure.lang.Var 和 clojure.core/thread-bound? 更改为仅当 Var 可设置为 true 时才返回。

0
by

评论由: alexmiller 提供

REPL示例?

0
by

评论由: joegallo 提供

当然,Alex -- 这里是今早我刚刚运行的repl示例。

`; nREPL 0.1.7
user> (def ^:dynamic set-me nil)

'user/set-me

user> (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? #'set-me) (set! set-me (inc set-me)))))))

'user/try-to-set

user> (try-to-set)
IllegalStateException Can't set!: set-me from non-binding thread clojure.lang.Var.set (Var.java:230)
user>`

0
by
参考: https://clojure.atlassian.net/browse/CLJ-1077 (由 pjstadig 报告)
...