Skip to content

Commit

Permalink
Merge pull request #3361 from armanbilge/fix/js-callbackstack-leak
Browse files Browse the repository at this point in the history
Fix `CallbackStack` leak on JS
  • Loading branch information
djspiewak authored Jan 15, 2023
2 parents 42e2503 + 0e3f967 commit 83412c5
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions core/js/src/main/scala/cats/effect/CallbackStack.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,22 @@ private final class CallbackStackOps[A](private val callbacks: js.Array[A => Uni
* Invokes *all* non-null callbacks in the queue, starting with the current one. Returns true
* iff *any* callbacks were invoked.
*/
@inline def apply(oc: A, _invoked: Boolean): Boolean = {
var i = callbacks.length - 1
var invoked = _invoked
while (i >= 0) {
val cb = callbacks(i)
if (cb ne null) {
cb(oc)
invoked = true
}
i -= 1
}
invoked
}
@inline def apply(oc: A, invoked: Boolean): Boolean =
callbacks
.asInstanceOf[js.Dynamic]
.reduceRight( // skips deleted indices, but there can still be nulls
(acc: Boolean, cb: A => Unit) =>
if (cb ne null) { cb(oc); true }
else acc,
invoked)
.asInstanceOf[Boolean]

/**
* Removes the current callback from the queue.
*/
@inline def clearCurrent(handle: CallbackStack.Handle): Unit = callbacks(handle) = null
@inline def clearCurrent(handle: Int): Unit =
// deleting an index from a js.Array makes it sparse (aka "holey"), so no memory leak
js.special.delete(callbacks, handle)

@inline def currentHandle(): CallbackStack.Handle = callbacks.length - 1

Expand Down

0 comments on commit 83412c5

Please sign in to comment.