A socket EVFILT_READ knote whose NOTE_LOWAT mark is below 1 is now always ready and reports the bytes in the receive buffer, 0 when it is empty, because FreeBSD 11.4 filt_soread returns kn_data >= kn_sdata and the bytes available are never negative. This holds for level-triggered and EV_CLEAR knotes and when EV_ADD changes the mark of an existing knote. A listening socket ignores the mark, as filt_solisten does. An EVFILT_WRITE mark below 1 still throws.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Keep both EVFILT_PROC (main) and EVFILT_SIGNAL (this PR) in Kqueue.cpp: the constants, the two knote functions, the filter check and the dispatch. Debt doc: main's EVFILT_PROC and pipe wording with the PR's signal text.
On Windows a pair is a loopback stream or two connected datagram sockets
rather than the console's local pair. After the peer closes, the first
stream send reaches a socket the host still accepts and succeeds, where
the console fails it with EPIPE, and an empty datagram receive waits on a
socket the host never signals, where the console fails it with
ECONNRESET; a datagram queued before the close is still delivered first.
Both answers now come from the pair's lost peer before the host is
waited on. Measured on a PS5 (13.60 and 11.60): send EPIPE (32) and
receive ECONNRESET (54).
The receive side asks the socket whether a datagram is queued rather than
whether bytes are queued, because a datagram sent with no payload still
has to be delivered: ioctlsocket answers 1 for one on this host, and
select answers readable, while a byte count of the socket as a whole
would answer 0 on a host that counts payload only. The Windows case now
sends an empty datagram before the close and expects it, then 54.
The FreeBSD permalink in the pthread_barrier debt entry covered _pthread_barrier_destroy; the count check it describes is at lines 97 to 104.
Co-authored-by: slopgobblercobbler <[email protected]>
ProsperoWeb (PRWB00001) 0.2.1 imports the three from libkernel. Only
libkernel_sys exported them, and a Linux run of the title does not load
libkernel_sys.prx, so the loader stopped with "undefined symbol:
LxIacrWiJ3w" before the title started.
Cpuset.cpp moves to libkernel whole, because cpuset and cpuset_setid
share its set table with cpuset_getid; its test and debt entry follow.
rfork_thread and sceKernelRdup move with the prototypes the title uses
and still throw.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The blocked mask of sigprocmask, _sigprocmask, pthread_sigmask and
sigsuspend was one process-wide set, so a thread changing its mask changed
every thread's, and scePthreadCreate did not hand the creating thread's mask
to the new thread. Each guest thread now has its own blocked mask and handler
holds, and a new thread starts with its creator's mask. The pending set stays
the process-wide one, so a signal that raise leaves pending is still taken by
sigwait and sigtimedwait on any thread and delivered by the first thread that
unblocks it. A SIGALRM expiry checks the mask of the thread that armed the
timer.
Fixes#2879.
Claude-Session: https://claude.ai/code/session_012SLQbhAiexxW6TtjYToW8a