// Reusable notification of an executor lifecycle transition.

///|
priv struct Completion {
  done : @ref.Ref[Bool]
  error : @ref.Ref[Error?]
  signal : @async.Queue[Unit]
}

///|
fn Completion::new() -> Completion {
  { done: Ref(false), error: Ref(None), signal: Queue(kind=Unbounded), }
}

///|
fn Completion::complete(self : Completion, error : Error?) -> Unit {
  if self.done.val {
    return
  }
  self.error.val = error
  self.done.val = true
  self.signal.close()
}

///|
async fn Completion::wait(self : Completion) -> Unit {
  if !self.done.val {
    ignore(self.signal.get()) catch {
      @aqueue.QueueAlreadyClosed => ()
      error => raise error
    }
  }
  if self.error.val is Some(error) {
    raise error
  }
}