A thread blocked in sceZlibWaitForDone was never woken by
sceZlibFinalize, so it waited for its whole timeout or forever.
Finalization now wakes every waiter, and a waiter that sees the
service finalized throws, since no source says what the console
returns. shadPS4 leaves such a waiter blocked.
sceZlibWaitForDone threw for any timeout and when no finished request
was pending. Wait on a condition variable that sceZlibInflate signals:
a null timeout blocks until a request finishes, and a timeout returns
0x81120027 (timed out) on expiry, as in shadPS4. The timeout is read
as microseconds, as SharpProspero documents for the PS5; shadPS4
reads milliseconds.
sceZlibFinalize threw while a finished request's result was unread.
Discard the stored results and the finished IDs not yet returned by
sceZlibWaitForDone instead. shadPS4 also returns success here and
never reports the abandoned requests; its next initialization clears
them. An ID from before finalization reports 0x81120002 afterwards.
sceZlibGetResult threw on a second call for the same request and on
an ID it did not hold. Return the same length and status on every
call, and 0x81120002 (not found) for an unknown ID, as shadPS4 does.
Null output pointers still throw.
sceZlibInflate threw when an earlier request's result had not been
read. Accept the request instead: every finished request keeps its
result, and sceZlibWaitForDone returns the finished IDs in submission
order, as shadPS4's done queue does. The PS5 completion order is
unverified and recorded in the technical debt entry.
Keep finished requests in a map keyed by request ID and their IDs in
a completion queue instead of a single optional result. This prepares
for several outstanding requests.
sceZlibWaitForDone now pops the completion queue, so it returns each
finished request once and no longer depends on whether its result was
read, as in shadPS4's done queue. A second wait for the same request
throws as before when nothing else is pending.
inflate returns Z_BUF_ERROR both when the output is full and when the
input ends early. sceZlibInflate treated every Z_BUF_ERROR with no
output space left as insufficient output, so a stream cut off after
its last data byte, such as one missing its Adler-32 trailer, reported
0x8112001C when the output capacity equalled its decoded length, and
0x811200FF with any larger buffer. Report insufficient output only
while input remains, as zlib's uncompress2 and miniz's mz_uncompress2
do and as the technical debt entry describes.