We're updating the issue view to help you get more done. 

clojure.core/sort is not thread-safe on Java collections with backing arrays

Description

If a (mutable) Java collection that exposes it's backing array is passed to c.c/sort in multiple threads, the collection will be concurrently modified in multiple threads.

1 2 3 4 5 6 user=> (def q (java.util.concurrent.ArrayBlockingQueue. 1)) #'user/q user=> (future (loop [] (.add q 1) (.remove q 1) (recur))) #object[clojure.core$future_call$reify__4393 0x4769b07b {:status :pending, :val nil}] user=> (take 3 (distinct (repeatedly #(sort q)))) ((1) () nil)

Approach: Convert coll to a seq before converting it to an array, thus preserving the original collection.

Patch: 0001-CLJ-1763-make-sort-thread-safe.patch

Alternate approaches:

1. Document in sort that, like Java arrays, Java collections backed by arrays are modified in-place.
2. Change RT.toArray() to defensively copy the array returned from a (non-IPersistentCollection) Java collection. This has a number of potential ramifications as this method is called from several paths.
3. For non-Clojure collections, could also use Collections.sort() instead of dumping to array and using Arrays.sort().

Environment

None

Status

Assignee

Unassigned

Reporter

Nicola Mometto

Labels

Approval

Triaged

Patch

Code

Priority

Minor