Merge pull request #3256 from Parlane/net_fix_poll

Don't send return-only events to poll
This commit is contained in:
Matthew Parlane 2015-11-16 16:13:49 +13:00
commit 1124be0568
1 changed files with 151 additions and 145 deletions

View File

@ -982,10 +982,20 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
case IOCTL_SO_POLL: case IOCTL_SO_POLL:
{ {
// Map Wii/native poll events types // Map Wii/native poll events types
unsigned int mapping[][2] = { struct
{ POLLIN, 0x0001 }, {
{ POLLOUT, 0x0008 }, int native;
int wii;
} mapping[] =
{
{ POLLRDNORM, 0x0001 },
{ POLLRDBAND, 0x0002 },
{ POLLPRI, 0x0004 },
{ POLLWRNORM, 0x0008 },
{ POLLWRBAND, 0x0010 },
{ POLLERR, 0x0020 },
{ POLLHUP, 0x0040 }, { POLLHUP, 0x0040 },
{ POLLNVAL, 0x0080 },
}; };
u32 unknown = Memory::Read_U32(BufferIn); u32 unknown = Memory::Read_U32(BufferIn);
@ -995,12 +1005,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
if (nfds == 0) if (nfds == 0)
ERROR_LOG(WII_IPC_NET, "Hidden POLL"); ERROR_LOG(WII_IPC_NET, "Hidden POLL");
pollfd_t* ufds = (pollfd_t*)malloc(sizeof(pollfd_t) * nfds); std::vector<pollfd_t> ufds(nfds);
if (ufds == nullptr)
{
ReturnValue = -1;
break;
}
for (int i = 0; i < nfds; ++i) for (int i = 0; i < nfds; ++i)
{ {
@ -1013,22 +1018,24 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
ufds[i].events = 0; ufds[i].events = 0;
for (auto& map : mapping) for (auto& map : mapping)
{ {
if (events & map[1]) if (events & map.wii)
ufds[i].events |= map[0]; ufds[i].events |= map.native;
unhandled_events &= ~map[1]; unhandled_events &= ~map.wii;
} }
DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL(%d) " DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL(%d) "
"Sock: %08x, Unknown: %08x, Events: %08x, " "Sock: %08x, Unknown: %08x, Events: %08x, "
"NativeEvents: %08x", "NativeEvents: %08x",
i, ufds[i].fd, unknown, events, ufds[i].events i, ufds[i].fd, unknown, events, ufds[i].events
); );
// Do not pass return-only events to the native poll
ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL);
if (unhandled_events) if (unhandled_events)
ERROR_LOG(WII_IPC_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events); ERROR_LOG(WII_IPC_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events);
} }
int ret = poll(ufds, nfds, timeout); int ret = poll(ufds.data(), nfds, timeout);
ret = WiiSockMan::GetNetErrorCode(ret, "SO_POLL", false); ret = WiiSockMan::GetNetErrorCode(ret, "SO_POLL", false);
for (int i = 0; i < nfds; ++i) for (int i = 0; i < nfds; ++i)
@ -1038,8 +1045,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
int revents = 0; int revents = 0;
for (auto& map : mapping) for (auto& map : mapping)
{ {
if (ufds[i].revents & map[0]) if (ufds[i].revents & map.native)
revents |= map[1]; revents |= map.wii;
} }
// No need to change fd or events as they are input only. // No need to change fd or events as they are input only.
@ -1047,9 +1054,8 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
//Memory::Write_U32(events, BufferOut + 0xc*i + 4); //events //Memory::Write_U32(events, BufferOut + 0xc*i + 4); //events
Memory::Write_U32(revents, BufferOut + 0xc*i + 8); //revents Memory::Write_U32(revents, BufferOut + 0xc*i + 8); //revents
DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d revents %08X events %08X", i, revents, ufds[i].events); DEBUG_LOG(WII_IPC_NET, "IOCTL_SO_POLL socket %d wevents %08X events %08X revents %08X", i, revents, ufds[i].events, ufds[i].revents);
} }
free(ufds);
ReturnValue = ret; ReturnValue = ret;
break; break;