sceNetAdhoc: Socket alerts don't stop calls that can complete at once

On a PSP (pspautotests net/adhoc/alerts), PtpConnect on a connected
socket and PtpFlush with nothing left to send return 0 with their alerts
set, and the poll alert reports ALERT alone in revents. A connection
PtpOpen started counts as connected once it's up, even if no call has
looked at it since.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 authored and Henrik Rydgård committed 2026-10-29 22:39:05 +01:00
1 parent 7e44dc7e8d
commit 0d089972a3
1 file changed
+19 -6
+19 -6
View File
@@ -3313,6 +3313,8 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock
if (sock->flags & ADHOC_F_ALERTPOLL) {
sock->alerted_flags |= ADHOC_F_ALERTPOLL;
// Reported as ALERT alone (pspautotests net/adhoc/alerts).
sds[i].revents = ADHOC_EV_ALERT;
return SCE_NET_ADHOC_ERROR_SOCKET_ALERTED;
}
@@ -5140,17 +5142,26 @@ int NetAdhocPtp_Connect(int id, int timeout, int flag, bool allowForcedConnect)
auto& ptpsocket = socket->data.ptp;
socket->nonblocking = flag;
// A connection PtpOpen started may have come up since.
if (ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT && !serverHasRelay) {
struct sockaddr_in peer;
socklen_t peerLen = sizeof(peer);
if (getpeername(ptpsocket.id, (struct sockaddr *)&peer, &peerLen) == 0) {
ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED;
}
}
// Connecting a connected socket returns 0 on the PSP, even with the connect alert set (pspautotests
// net/adhoc/alerts). Phantasy Star Portable 2 does that.
if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED)
return 0;
if (socket->flags & ADHOC_F_ALERTCONNECT) {
socket->alerted_flags |= ADHOC_F_ALERTCONNECT;
return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_SOCKET_ALERTED, "socket alerted");
}
// Connecting a connected socket returns 0 on the PSP (pspautotests net/adhoc/alerts). Phantasy Star
// Portable 2 does that.
if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED)
return 0;
// Valid Client Socket
if (ptpsocket.state == ADHOC_PTP_STATE_CLOSED || ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT) {
hleEatMicro(50);
@@ -5918,7 +5929,9 @@ static int sceNetAdhocPtpFlush(MIPSState *mips, int id, int timeout, int nonbloc
auto& ptpsocket = socket->data.ptp;
socket->nonblocking = nonblock;
if (socket->flags & ADHOC_F_ALERTFLUSH) {
// A flush with nothing left to send returns 0 even with the flush alert set (pspautotests
// net/adhoc/alerts). Data sent on a connected socket is already with the host.
if ((socket->flags & ADHOC_F_ALERTFLUSH) && ptpsocket.state != ADHOC_PTP_STATE_ESTABLISHED) {
socket->alerted_flags |= ADHOC_F_ALERTFLUSH;
return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_SOCKET_ALERTED, "socket alerted");