sceRudpPollCancel waited until no wait was registered, so a wait that
started during the drain kept it blocked, forever for an infinite one.
Waits registered when the cancel starts now move to a draining count,
and the cancel returns once those have left. A scope guard releases each
wait's registration on every exit, retaking the lock if the wait had
dropped it, so an exception in the condition wait no longer leaves a
registration that a later cancel can never drain. Reported by
@MarcZX10, @thepoppfish, @adriadam10 and @oneandonlydean; the guard
follows @thepoppfish's repair.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A cancel with no waiter is kept once for that poll and makes its next
sceRudpPollWait return 0x80770014, also with a zero timeout. A cancel
with waiters wakes all of them with 0x80770014 and returns once none is
left. Behaviour from @BunnyFl's execution of the 13.42 libSceRudp.sprx
in #10954.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Implement sceRudpPollCreate, sceRudpPollControl, sceRudpPollWait and
sceRudpPollDestroy with the PS Vita signatures and argument checks.
sceRudpTerminate removes the context from every poll and sceRudpEnd
destroys the polls and wakes their waiters.
Co-Authored-By: Claude Opus 5.5 <[email protected]>