mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
Merge pull request #14060 from ANR2ME/adhoc
[Adhoc] Fix possible lock issue and Updated PdpStat
This commit is contained in:
3 files changed
+34
-9
No files matched your search
+25
-3
@@ -1896,13 +1896,35 @@ uint16_t getLocalPort(int sock) {
|
||||
return ntohs(localAddr.sin_port);
|
||||
}
|
||||
|
||||
u_long getAvailToRecv(int sock) {
|
||||
u_long getAvailToRecv(int sock, int udpBufferSize) {
|
||||
u_long n = 0; // Typical MTU size is 1500
|
||||
int err = -1;
|
||||
#if defined(_WIN32) // May not be available on all platform
|
||||
ioctlsocket(sock, FIONREAD, &n);
|
||||
err = ioctlsocket(sock, FIONREAD, &n);
|
||||
#else
|
||||
ioctl(sock, FIONREAD, &n);
|
||||
err = ioctl(sock, FIONREAD, &n);
|
||||
#endif
|
||||
if (err < 0)
|
||||
return 0;
|
||||
|
||||
if (udpBufferSize > 0 && n > 0) {
|
||||
// Cap number of bytes of full DGRAM message(s?) up to buffer size
|
||||
static int lastUdpBufSize = 0;
|
||||
static char* buf = NULL;
|
||||
if (udpBufferSize > lastUdpBufSize) {
|
||||
// Reusing temp buffer to prevent causing too many fragmentation due to repeated alloc -> free (was getting out of memory issue)
|
||||
char *tmp = (char*)realloc(buf, udpBufferSize);
|
||||
if (tmp) {
|
||||
buf = tmp;
|
||||
lastUdpBufSize = udpBufferSize;
|
||||
}
|
||||
}
|
||||
// Does each recv can only received one message?
|
||||
err = recvfrom(sock, buf, udpBufferSize, MSG_PEEK | MSG_NOSIGNAL | MSG_TRUNC, NULL, NULL);
|
||||
//free(buf); // Repeated alloc -> free seems to cause too many fragmentation and ended getting out of memory due to too many alloc -> free
|
||||
if (err >= 0)
|
||||
return (u_long)err;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1271,8 +1271,10 @@ bool isPrivateIP(uint32_t ip);
|
||||
|
||||
/*
|
||||
* Get Number of bytes available in buffer to be Received
|
||||
* @param sock fd
|
||||
* @param udpBufferSize (UDP only)
|
||||
*/
|
||||
u_long getAvailToRecv(int sock);
|
||||
u_long getAvailToRecv(int sock, int udpBufferSize = 0);
|
||||
|
||||
/*
|
||||
* Get UDP Socket Max Message Size
|
||||
|
||||
@@ -2943,10 +2943,9 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) {
|
||||
auto sock = adhocSockets[j];
|
||||
if (sock != NULL && sock->type == SOCK_PDP) {
|
||||
// Set available bytes to be received. With FIONREAD There might be ghosting 1 byte in recv buffer when remote peer's socket got closed (ie. Warriors Orochi 2) Attempting to recv this ghost 1 byte will result to socket error 10054 (may need to disable SIO_UDP_CONNRESET error)
|
||||
sock->data.pdp.rcv_sb_cc = getAvailToRecv(sock->data.pdp.id);
|
||||
// TODO: It seems real PSP respecting the socket buffer size arg, so we may need to cap the value to the buffer size arg since we use larger buffer, but may cause Warriors Orochi 2 to get slower performance.
|
||||
// Note: Capping available data on UDP/PDP can causes data loss if the game tried to read the whole capped buffer size while containing partial/truncated message.
|
||||
//sock->data.pdp.rcv_sb_cc = std::min(sock->data.pdp.rcv_sb_cc, (u32_le)sock->buffer_size);
|
||||
// It seems real PSP respecting the socket buffer size arg, so we may need to cap the value up to the buffer size arg since we use larger buffer, for PDP/UDP the total size must not contains partial/truncated message to avoid data loss.
|
||||
// TODO: We may need to manage PDP messages ourself by reading each msg 1-by-1 and moving it to our internal buffer(msg array) in order to calculate the correct messages size that can fit into buffer size when there are more than 1 messages in the recv buffer (simulate FIONREAD)
|
||||
sock->data.pdp.rcv_sb_cc = getAvailToRecv(sock->data.pdp.id, sock->buffer_size);
|
||||
|
||||
// Copy Socket Data from Internal Memory
|
||||
memcpy(&buf[i], &sock->data.pdp, sizeof(SceNetAdhocPdpStat));
|
||||
@@ -4661,8 +4660,10 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int
|
||||
// Create PDP Socket
|
||||
int sock = sceNetAdhocPdpCreate((const char*)&item->mac, static_cast<int>(item->port), item->rxbuflen, 0);
|
||||
item->socket = sock;
|
||||
if (sock < 1)
|
||||
if (sock < 1) {
|
||||
peerlock.unlock();
|
||||
return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_PORT_IN_USE, "adhoc matching port in use");
|
||||
}
|
||||
|
||||
// Create & Start the Fake PSP Thread ("matching_ev%d" and "matching_io%d")
|
||||
netAdhocValidateLoopMemory();
|
||||
|
||||
Reference in new issue
Block a user