diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index 79214e8e4..e3d4b17f5 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -1071,14 +1071,14 @@ int APS5_VABI sceNetEpollWait(int eid, NetEpollEvent* events, int maxevents, int for (std::size_t index = 0; index < descriptors.size(); ++index) { descriptors[index].fd = native_sockets[index]->value; if (registered_events[index].events & 1) descriptors[index].events |= POLLRDNORM; - if (registered_events[index].events & 4) descriptors[index].events |= POLLWRNORM; + if (registered_events[index].events & 2) descriptors[index].events |= POLLWRNORM; } #else std::vector descriptors(registered_events.size()); for (std::size_t index = 0; index < descriptors.size(); ++index) { descriptors[index].fd = native_sockets[index]->value; if (registered_events[index].events & 1) descriptors[index].events |= POLLIN; - if (registered_events[index].events & 4) descriptors[index].events |= POLLOUT; + if (registered_events[index].events & 2) descriptors[index].events |= POLLOUT; } #endif const auto now = std::chrono::steady_clock::now(); @@ -1108,10 +1108,10 @@ int APS5_VABI sceNetEpollWait(int eid, NetEpollEvent* events, int maxevents, int std::uint32_t guest_events = 0; #ifdef _WIN32 if (native_events & (POLLRDNORM | POLLPRI)) guest_events |= 1; - if (native_events & POLLWRNORM) guest_events |= 4; + if (native_events & POLLWRNORM) guest_events |= 2; #else if (native_events & (POLLIN | POLLPRI)) guest_events |= 1; - if (native_events & POLLOUT) guest_events |= 4; + if (native_events & POLLOUT) guest_events |= 2; #endif if (native_events & POLLERR) guest_events |= 8; if (native_events & POLLHUP) guest_events |= 16; diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index 993e40205..6eb3854ea 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -149,6 +149,38 @@ static void CheckEmptyEpoll() { } } +static void CheckEpollWritable() { + std::array address{16, 2, 0, 0, 127, 0, 0, 1}; + const int receiver = sceNetSocket("epoll-receiver", 2, 2, 17); + const int sender = sceNetSocket("epoll-sender", 2, 2, 17); + Require(receiver >= 0 && sender >= 0); + Require(sceNetBind_nid_postfix(receiver, address.data(), address.size()) == 0); + std::uint32_t size = address.size(); + Require(sceNetGetsockname(receiver, address.data(), &size) == 0 && size == address.size()); + const int epoll = sceNetEpollCreate("epoll-writable", 0); + Require(epoll >= 0); + NetEpollEvent registration{}; + registration.events = 2; + registration.ident = static_cast(sender); + registration.data.u32 = 41; + Require(sceNetEpollControl(epoll, 1, sender, ®istration) == 0); + NetEpollEvent ready{}; + Require(sceNetEpollWait(epoll, &ready, 1, 1000000) == 1); + Require(ready.events == 2 && ready.ident == static_cast(sender) && ready.data.u32 == 41); + Require(sceNetEpollControl(epoll, 3, sender, nullptr) == 0); + const char payload[] = "epoll"; + char peeked[sizeof(payload)]{}; + Require(sceNetSendto(sender, payload, sizeof(payload), 0, address.data(), address.size()) == sizeof(payload)); + Require(sceNetRecv(receiver, peeked, sizeof(peeked), 2) == sizeof(payload)); + registration.events = 3; + registration.ident = static_cast(receiver); + Require(sceNetEpollControl(epoll, 1, receiver, ®istration) == 0); + Require(sceNetEpollWait(epoll, &ready, 1, 1000000) == 1); + Require(ready.events == 3 && ready.ident == static_cast(receiver) && ready.data.u32 == 41); + Require(sceNetEpollDestroy(epoll) == 0); + Require(sceNetSocketClose(sender) == 0 && sceNetSocketClose(receiver) == 0); +} + static void CheckReceiveTimeout(int receiver, int sender, const std::array& address) { const int timeout = 50000; Require(sceNetSetsockopt(receiver, 0xffff, 0x1006, &timeout, sizeof(timeout)) == 0); @@ -353,6 +385,7 @@ int main() { Require(sceNetInit_nid_postfix() == 0); CheckPoolStats(); CheckEmptyEpoll(); + CheckEpollWritable(); CheckAddressText(2, "127.0.0.1"); CheckAddressText(2, "255.255.255.255"); CheckAddressText(28, "::1");