/// <summary>
/// Wait for an event flag for a given bit pattern with callback.
/// </summary>
/// <param name="EventId">The event ID returned by <see cref="sceKernelCreateEventFlag"/>.</param>
/// <param name="Bits">The bit pattern to poll for.</param>
/// <param name="Wait">Wait type, one or more of PspEventFlagWaitTypes or'ed together</param>
/// <param name="OutBits">The bit pattern that was matched.</param>
/// <param name="Timeout">Timeout in microseconds</param>
/// <param name="HandleCallbacks"></param>
/// <returns>
/// ERROR_KERNEL_NOT_FOUND_EVENT_FLAG - If can't find the eventFlag
/// ERROR_KERNEL_WAIT_TIMEOUT - If there was a timeout
/// 0 - On success
/// </returns>
public int _sceKernelWaitEventFlagCB(HleEventFlag EventFlag, uint Bits, EventFlagWaitTypeSet Wait, uint* OutBits, uint* Timeout, bool HandleCallbacks)
{
if ((Wait & ~(EventFlagWaitTypeSet.MaskValidBits)) != 0) throw (new SceKernelException(SceKernelErrors.ERROR_KERNEL_ILLEGAL_MODE));
if (Bits == 0) throw (new SceKernelException(SceKernelErrors.ERROR_KERNEL_EVENT_FLAG_ILLEGAL_WAIT_PATTERN));
bool TimedOut = false;
var PreviousPattern = EventFlag.Info.CurrentPattern;
ThreadManager.Current.SetWaitAndPrepareWakeUp(
HleThread.WaitType.Semaphore,
String.Format("_sceKernelWaitEventFlagCB(EventId={0}, Bits={1:X}, Wait={2})", EventFlag.GetUidIndex(InjectContext), Bits, Wait),
EventFlag,
WakeUpCallback =>
{
if (Timeout != null)
{
PspRtc.RegisterTimerInOnce(TimeSpanUtils.FromMicroseconds(*Timeout), () =>
{
TimedOut = true;
*Timeout = 0;
WakeUpCallback();
});
}
EventFlag.AddWaitingThread(new HleEventFlag.WaitThread()
{
HleThread = ThreadManager.Current,
BitsToMatch = Bits,
WaitType = Wait,
WakeUpCallback = () => { WakeUpCallback(); },
OutBits = OutBits,
});
}, HandleCallbacks: HandleCallbacks);
if (OutBits != null)
{
*OutBits = PreviousPattern;
}
if (TimedOut)
{
throw(new SceKernelException(SceKernelErrors.ERROR_KERNEL_WAIT_TIMEOUT));
}
//throw(new NotImplementedException());
return 0;
}