/* Function waits for a given event to fire, or for an optional timeout to expire. */
EFI_STATUS EFIAPI WaitForSingleEvent(IN EFI_EVENT Event, IN UINT64 Timeout OPTIONAL)
/* Function waits for a given event to fire, or for an optional timeout to expire. */
EFI_STATUS EFIAPI WaitForSingleEvent(IN EFI_EVENT Event, IN UINT64 Timeout OPTIONAL)
{
  EFI_STATUS  Status;
  UINTN       Index;
  EFI_EVENT   TimerEvent;
  EFI_EVENT   WaitList[2];
  if (Timeout != 0) {
    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
    if (!EFI_ERROR (Status)) {
      gBS->SetTimer (
             TimerEvent,
             TimerRelative,
             Timeout
             );
      WaitList[0] = Event;
      WaitList[1] = TimerEvent;
      Status      = gBS->WaitForEvent (2, WaitList, &Index);
      gBS->CloseEvent (TimerEvent);
      if (!EFI_ERROR (Status) && (Index == 1)) {
        Status = EFI_TIMEOUT;
      }
    }
  } else {
    Status = gBS->WaitForEvent (1, &Event, &Index);
    ASSERT (!EFI_ERROR (Status));
    ASSERT (Index == 0);
  }
  return Status;
}