Skip to content

Blocking code is not always properly handled #1543

@ghik

Description

@ghik

Reproduction

import monix.eval.Task
import monix.execution.Scheduler

object Bug extends App {
  implicit val scheduler: Scheduler = Scheduler.forkJoin(1, 128)

  val task = Task.async[Unit](_.onSuccess(())).map { _ =>
    Task.evalAsync(println("foo")).runSyncUnsafe()
  }
  task.executeAsync.runSyncUnsafe()
}

Current behaviour

Deadlock

Expectation

No deadlock. The blocking .runSyncUnsafe() call should prompt the underlying thread pool to allocate a new thread in place of the blocked one.

Analysis

The culprit is monix.execution.internal.Trampoline.trampolineContext which overrides the parent BlockContext that is responsible for wrapping the blocking code in ForkJoinPool.managedBlock

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions