mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Adhoc: Stop waiting for a login that has already failed
sceNetAdhocctlInit waits until the friend finder has logged into the adhoc server, polling in emulated time but giving up only after 5s of wall time. The friend finder makes one attempt per login request, and it too waited the full 5s on a connection that had already been refused, because it only looked for success. Now it checks the socket error and gives up at once, and records the failure so the wait ends with it. In headless, which runs far ahead of real time, Gods Eater Burst sat in this wait for its whole run. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
2cd84012d0
commit
7ec860c24f
4 files changed
+21
-1
No files matched your search
@@ -45,3 +45,4 @@ u32 matchingThreadHackAddr = 0;
|
||||
u32_le matchingThreadCode[3];
|
||||
|
||||
bool g_adhocServerConnected = false;
|
||||
std::atomic<bool> g_adhocServerLoginFailed(false);
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "CommonTypes.h"
|
||||
#include "Swap.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
extern u32 dummyThreadHackAddr;
|
||||
@@ -52,5 +53,8 @@ extern u32 matchingThreadHackAddr;
|
||||
extern u32_le matchingThreadCode[3];
|
||||
|
||||
extern bool g_adhocServerConnected;
|
||||
// Set by the friend finder when its attempt to connect and log in for the latest login request
|
||||
// failed, so a caller waiting on that login can stop waiting.
|
||||
extern std::atomic<bool> g_adhocServerLoginFailed;
|
||||
|
||||
constexpr u32 defaultLastRecvDelta = 10000; //10000 usec worked well for games published by Falcom (ie. Ys vs Sora Kiseki, Vantage Master Portable)
|
||||
@@ -1420,6 +1420,7 @@ int friendFinder() {
|
||||
}
|
||||
else {
|
||||
g_adhocServerConnected = false;
|
||||
g_adhocServerLoginFailed = true;
|
||||
shutdown((int)metasocket, SD_BOTH);
|
||||
closesocket((int)metasocket);
|
||||
metasocket = (int)INVALID_SOCKET;
|
||||
@@ -2251,6 +2252,16 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
||||
return iResult;
|
||||
|
||||
done = (IsSocketReady((int)metasocket, false, true) > 0);
|
||||
if (done) {
|
||||
// Writable can also mean the attempt failed (refused, say). Then there's no point
|
||||
// waiting out the timeout.
|
||||
int soError = 0;
|
||||
socklen_t soErrorLen = sizeof(soError);
|
||||
if (getsockopt((int)metasocket, SOL_SOCKET, SO_ERROR, (char *)&soError, &soErrorLen) == 0 && soError != 0) {
|
||||
errorcode = soError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen = sizeof(sin);
|
||||
memset(&sin, 0, sinlen);
|
||||
|
||||
@@ -560,7 +560,8 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) {
|
||||
}
|
||||
|
||||
// Retry until successfully sent. Login packet sent after successfully connected to Adhoc Server (indicated by networkInited), so we're not sending Login again here
|
||||
if ((req.opcode == OPCODE_LOGIN && !g_adhocServerConnected) || (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK))) {
|
||||
// A login stops waiting early once the friend finder has tried and failed to connect.
|
||||
if ((req.opcode == OPCODE_LOGIN && !g_adhocServerConnected && !g_adhocServerLoginFailed) || (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK))) {
|
||||
u64 now = (u64)(time_now_d() * 1000000.0);
|
||||
if (now - adhocctlStartTime <= static_cast<u64>(adhocDefaultTimeout) + 500) {
|
||||
// Try again in another 0.5ms until timedout.
|
||||
@@ -2001,6 +2002,7 @@ int sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) {
|
||||
|
||||
adhocctlEvents.clear();
|
||||
netAdhocctlInited = true; //needed for cleanup during AdhocctlTerm even when it failed to connect to Adhoc Server (since it's being faked as success)
|
||||
g_adhocServerLoginFailed = false;
|
||||
isAdhocctlNeedLogin = true;
|
||||
|
||||
// Create fake PSP Thread for callback
|
||||
@@ -3191,6 +3193,7 @@ int sceNetAdhocctlScan() {
|
||||
// Only scan when in Disconnected state, otherwise AdhocServer will kick you out
|
||||
if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED && !isAdhocctlBusy) {
|
||||
isAdhocctlBusy = true;
|
||||
g_adhocServerLoginFailed = false;
|
||||
isAdhocctlNeedLogin = true;
|
||||
adhocctlState = ADHOCCTL_STATE_SCANNING;
|
||||
adhocctlCurrentMode = ADHOCCTL_MODE_NORMAL;
|
||||
@@ -3684,6 +3687,7 @@ int NetAdhocctl_Create(const char *groupName) {
|
||||
// Disconnected State
|
||||
if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED && !isAdhocctlBusy) {
|
||||
isAdhocctlBusy = true;
|
||||
g_adhocServerLoginFailed = false;
|
||||
isAdhocctlNeedLogin = true;
|
||||
|
||||
// Set Network Name
|
||||
|
||||
Reference in new issue
Block a user