Skip to content

Commit 2d3059d

Browse files
committed
Use a js.Array to hold enqueued references in ReferenceQueue.
Since FIFO ordering is not actually required, we use the `js.Array` in stack mode.
1 parent 0439dad commit 2d3059d

File tree

1 file changed

+12
-20
lines changed

1 file changed

+12
-20
lines changed

src/main/scala/java/lang/ref/ReferenceQueue.scala

+12-20
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ package java.lang.ref
1515
import scala.scalajs.js
1616

1717
class ReferenceQueue[T] {
18-
import ReferenceQueue._
19-
20-
private[this] var first: Node[T] = null
21-
private[this] var last: Node[T] = null
18+
/** The "enqueued" References.
19+
*
20+
* Despite the name, this is used more as a stack (LIFO) than as a queue
21+
* (FIFO). The JavaDoc of `ReferenceQueue` does not actually prescribe FIFO
22+
* ordering, and experimentation shows that the JVM implementation does not
23+
* guarantee that ordering.
24+
*/
25+
private[this] val enqueuedRefs = js.Array[Reference[_ <: T]]()
2226

2327
private[this] val finalizationRegistry = {
2428
new js.FinalizationRegistry[T, Reference[_ <: T], Reference[_ <: T]]({
@@ -37,31 +41,19 @@ class ReferenceQueue[T] {
3741
false
3842
} else {
3943
ref.enqueued = true
40-
val newNode = new Node[T](ref, null)
41-
if (last == null)
42-
first = newNode
43-
else
44-
last.next = newNode
45-
last = newNode
44+
enqueuedRefs.push(ref)
4645
true
4746
}
4847
}
4948

5049
def poll(): Reference[_ <: T] = {
51-
val result = first
52-
if (result != null) {
53-
first = result.next
54-
result.ref
55-
} else {
50+
if (enqueuedRefs.length == 0)
5651
null
57-
}
52+
else
53+
enqueuedRefs.pop()
5854
}
5955

6056
// Not implemented because they have a blocking contract:
6157
//def remove(timeout: Long): Reference[_ <: T] = ???
6258
//def remove(): Reference[_ <: T] = ???
6359
}
64-
65-
private object ReferenceQueue {
66-
private final class Node[T](val ref: Reference[_ <: T], var next: Node[T])
67-
}

0 commit comments

Comments
 (0)