mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
sceNetAdhoc: Measure socket and game mode timeouts in emulated time
The timeouts of blocking socket calls and of entering game mode are the PSP's, but they were measured on the wall clock, so they came out shorter in PSP time whenever emulation ran fast or slow. The wait for the ad hoc server, which is a host-side round trip, stays on the wall clock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b707ff4306
commit
e7548e1bea
3 files changed
+19
-11
No files matched your search
@@ -85,6 +85,7 @@ SceNetAdhocctlPeerInfo * friends = NULL;
|
||||
SceNetAdhocctlScanInfo * networks = NULL;
|
||||
SceNetAdhocctlScanInfo * newnetworks = NULL;
|
||||
u64 adhocctlStartTime = 0;
|
||||
u64 gameModeEnterTimeUs = 0;
|
||||
std::atomic<bool> isAdhocctlNeedLogin = false;
|
||||
bool isAdhocctlBusy = false;
|
||||
int adhocctlState = ADHOCCTL_STATE_DISCONNECTED;
|
||||
@@ -1641,7 +1642,7 @@ void friendFinderPoll() {
|
||||
uint64_t now = time_now_d() * 1000000.0; // Use time_now_d()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable
|
||||
|
||||
// Calculate EnterGameMode Timeout to prevent waiting forever for disconnected players
|
||||
if (isAdhocctlBusy && adhocctlState == ADHOCCTL_STATE_DISCONNECTED && adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE && netAdhocGameModeEntered && static_cast<s64>(now - adhocctlStartTime) > netAdhocEnterGameModeTimeout) {
|
||||
if (isAdhocctlBusy && adhocctlState == ADHOCCTL_STATE_DISCONNECTED && adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE && netAdhocGameModeEntered && static_cast<s64>(CoreTiming::GetGlobalTimeUs() - gameModeEnterTimeUs) > netAdhocEnterGameModeTimeout) {
|
||||
netAdhocGameModeEntered = false;
|
||||
// A joiner's GAMEMODE is queued as soon as the server answers, and held until the host shows up.
|
||||
// It must not come after all (pspautotests net/adhoc/gamemode).
|
||||
|
||||
@@ -818,6 +818,8 @@ extern std::atomic<bool> friendFinderRunning;
|
||||
extern SceNetAdhocctlPeerInfo * friends;
|
||||
extern SceNetAdhocctlScanInfo * networks;
|
||||
extern u64 adhocctlStartTime;
|
||||
// When CreateEnterGameMode or JoinEnterGameMode was called, in emulated time: its timeout is a PSP-side one.
|
||||
extern u64 gameModeEnterTimeUs;
|
||||
extern std::atomic<bool> isAdhocctlNeedLogin;
|
||||
extern bool isAdhocctlBusy;
|
||||
extern int adhocctlState;
|
||||
|
||||
+15
-10
@@ -1053,7 +1053,7 @@ int DoBlockingPdpRecv(AdhocSocketRequest& req, s64& result) {
|
||||
memset(&sin, 0, sinlen);
|
||||
recvfrom(pdpsocket.id, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen);
|
||||
// Try again later, until timeout reached
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout != 0 && now - req.startTime > req.timeout) {
|
||||
result = SCE_NET_ADHOC_ERROR_TIMEOUT;
|
||||
DEBUG_LOG(Log::sceNet, "sceNetAdhocPdpRecv[%i]: Discard Timeout", req.id);
|
||||
@@ -1103,7 +1103,7 @@ int DoBlockingPdpRecv(AdhocSocketRequest& req, s64& result) {
|
||||
}
|
||||
// On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound yet), may need to disable SIO_UDP_CONNRESET error
|
||||
else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ECONNRESET) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
// Try again later
|
||||
return -1;
|
||||
@@ -1215,7 +1215,7 @@ int DoBlockingPdpSend(AdhocSocketRequest& req, s64& result, AdhocSendTargets& ta
|
||||
}
|
||||
else {
|
||||
if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK)) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
retry = true;
|
||||
}
|
||||
@@ -1340,7 +1340,7 @@ int DoBlockingPtpSend(AdhocSocketRequest& req, s64& result) {
|
||||
result = 0;
|
||||
}
|
||||
else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || (ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT && (sockerr == ENOTCONN || connectInProgress(sockerr))))) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1456,7 +1456,7 @@ int DoBlockingPtpRecv(AdhocSocketRequest& req, s64& result) {
|
||||
result = 0;
|
||||
}
|
||||
else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || (ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT && (sockerr == ENOTCONN || connectInProgress(sockerr))))) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1632,7 +1632,7 @@ int DoBlockingPtpAccept(AdhocSocketRequest& req, s64& result) {
|
||||
result = newid;
|
||||
}
|
||||
else if (ret == 0 || (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK))) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1814,7 +1814,7 @@ int DoBlockingPtpConnect(AdhocSocketRequest& req, s64& result, AdhocSendTargets&
|
||||
|
||||
// Still in progress, try again next time until Timedout
|
||||
if (ptpsocket.state != ADHOC_PTP_STATE_ESTABLISHED) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
// Try again later
|
||||
return -1;
|
||||
@@ -1855,7 +1855,7 @@ int DoBlockingPtpFlush(AdhocSocketRequest& req, s64& result) {
|
||||
result = 0;
|
||||
|
||||
if (sockerr == EAGAIN || sockerr == EWOULDBLOCK) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
if (req.timeout == 0 || now - req.startTime <= req.timeout) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1877,7 +1877,7 @@ int DoBlockingAdhocPollSocket(AdhocSocketRequest& req, s64& result) {
|
||||
// A disconnected socket or a poll alert ends the wait at once.
|
||||
ret = SCE_NET_ADHOC_ERROR_EXCEPTION_EVENT;
|
||||
} else if (ret == 0) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
u64 now = CoreTiming::GetGlobalTimeUs();
|
||||
// A timeout of 0 waits forever, like the rest of sceNet.
|
||||
if (static_cast<int>(req.timeout) <= 0 || now - req.startTime <= req.timeout) {
|
||||
return -1;
|
||||
@@ -2019,7 +2019,8 @@ int WaitBlockingAdhocSocket(u64 threadSocketId, int type, int pspSocketId, void*
|
||||
if (tmout > 0)
|
||||
tmout = std::max(tmout, minSocketTimeoutUS);
|
||||
|
||||
u64 startTime = (u64)(time_now_d() * 1000000.0);
|
||||
// Timeouts are the PSP's, so they run on the emulated clock.
|
||||
u64 startTime = CoreTiming::GetGlobalTimeUs();
|
||||
adhocSocketRequests[threadSocketId] = { type, pspSocketId, buffer, len, tmout, startTime, remoteMAC, remotePort };
|
||||
// Some games (ie. Hitman Reborn Battle Arena 2) are using as small as 50 usec timeout
|
||||
CoreTiming::ScheduleEvent(usToCycles(1), adhocSocketNotifyEvent, threadSocketId);
|
||||
@@ -2179,6 +2180,8 @@ void __NetAdhocDoState(PointerWrap &p) {
|
||||
Do(p, isAdhocctlBusy);
|
||||
Do(p, netAdhocGameModeEntered);
|
||||
Do(p, netAdhocEnterGameModeTimeout);
|
||||
// Not saved: a game mode being entered gets its whole timeout again after a load.
|
||||
gameModeEnterTimeUs = CoreTiming::GetGlobalTimeUs();
|
||||
}
|
||||
else {
|
||||
isAdhocctlBusy = false;
|
||||
@@ -4447,6 +4450,7 @@ int NetAdhocctl_CreateEnterGameMode(const char* group_name, int game_type, int n
|
||||
adhocConnectionType = ADHOC_CREATE;
|
||||
netAdhocGameModeEntered = true;
|
||||
netAdhocEnterGameModeTimeout = timeout;
|
||||
gameModeEnterTimeUs = CoreTiming::GetGlobalTimeUs();
|
||||
return NetAdhocctl_Create(group_name);
|
||||
}
|
||||
|
||||
@@ -4509,6 +4513,7 @@ static int sceNetAdhocctlJoinEnterGameMode(MIPSState *mips, const char * group_n
|
||||
adhocConnectionType = ADHOC_JOIN;
|
||||
netAdhocGameModeEntered = true;
|
||||
netAdhocEnterGameModeTimeout = timeout;
|
||||
gameModeEnterTimeUs = CoreTiming::GetGlobalTimeUs();
|
||||
return hleLogDebug(Log::sceNet, NetAdhocctl_Create(group_name));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user