function* main() {
    actual.push(yield startDef.promise)

    try {
      actual.push(yield io.all([io.call(subroutine1), io.call(subroutine2)]))
    } finally {
      if (yield io.cancelled()) actual.push(yield 'cancelled')
    }
  }
Breaking change in 10.0: Since now attached forks are cancelled when their parent is cancelled
    cancellation of main will trigger in order: 1. cancel parent (main) 2. then cancel children (subroutine)
     Join cancellation has the following semantics: cancellation of a task triggers cancellation of all its
    joiners (similar to promise1.then(promise2): promise2 depends on promise1, if promise1 os cancelled,
    then so promise2 must be cancelled).
     In the present test, main is joining on of its proper children, so this would cause an endless loop, but
    since cancellation is noop on an already terminated task the deadlock wont happen