forked from eden-emu/eden
		
	network, sockets: Replace POLL_IN, POLL_OUT, etc. constants with an enum class PollEvents
				
					
				
			Actually, two enum classes, since for some reason there are two separate yet identical `PollFD` types used in the codebase. I get that one is ABI-compatible with the Switch while the other is an abstract type used for the host, but why not use `WSAPOLLFD` directly for the latter? Anyway, why make this change? Because on Apple platforms, `POLL_IN`, `POLL_OUT`, etc. (with an underscore) are defined as macros in <sys/signal.h>. (This is inherited from FreeBSD.) So defining a variable with the same name causes a compile error. I could just rename the variables, but while I was at it I thought I might as well switch to an enum for stronger typing. Also, change the type used for values copied directly to/from the `events` and `revents` fields of the host *native* `pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct canonical type on both Unix and Windows.
This commit is contained in:
		
							parent
							
								
									5933667cb8
								
							
						
					
					
						commit
						0791082b43
					
				
					 6 changed files with 82 additions and 71 deletions
				
			
		|  | @ -489,18 +489,18 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::vector<u | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (PollFD& pollfd : fds) { |     for (PollFD& pollfd : fds) { | ||||||
|         ASSERT(pollfd.revents == 0); |         ASSERT(False(pollfd.revents)); | ||||||
| 
 | 
 | ||||||
|         if (pollfd.fd > static_cast<s32>(MAX_FD) || pollfd.fd < 0) { |         if (pollfd.fd > static_cast<s32>(MAX_FD) || pollfd.fd < 0) { | ||||||
|             LOG_ERROR(Service, "File descriptor handle={} is invalid", pollfd.fd); |             LOG_ERROR(Service, "File descriptor handle={} is invalid", pollfd.fd); | ||||||
|             pollfd.revents = 0; |             pollfd.revents = PollEvents{}; | ||||||
|             return {0, Errno::SUCCESS}; |             return {0, Errno::SUCCESS}; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; |         const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; | ||||||
|         if (!descriptor) { |         if (!descriptor) { | ||||||
|             LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); |             LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); | ||||||
|             pollfd.revents = POLL_NVAL; |             pollfd.revents = PollEvents::Nval; | ||||||
|             return {0, Errno::SUCCESS}; |             return {0, Errno::SUCCESS}; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -510,7 +510,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::vector<u | ||||||
|         Network::PollFD result; |         Network::PollFD result; | ||||||
|         result.socket = file_descriptors[pollfd.fd]->socket.get(); |         result.socket = file_descriptors[pollfd.fd]->socket.get(); | ||||||
|         result.events = TranslatePollEventsToHost(pollfd.events); |         result.events = TranslatePollEventsToHost(pollfd.events); | ||||||
|         result.revents = 0; |         result.revents = Network::PollEvents{}; | ||||||
|         return result; |         return result; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -69,10 +69,22 @@ struct SockAddrIn { | ||||||
|     std::array<u8, 8> zeroes; |     std::array<u8, 8> zeroes; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum class PollEvents : u16 { | ||||||
|  |     // Using Pascal case because IN is a macro on Windows.
 | ||||||
|  |     In = 1 << 0, | ||||||
|  |     Pri = 1 << 1, | ||||||
|  |     Out = 1 << 2, | ||||||
|  |     Err = 1 << 3, | ||||||
|  |     Hup = 1 << 4, | ||||||
|  |     Nval = 1 << 5, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | DECLARE_ENUM_FLAG_OPERATORS(PollEvents); | ||||||
|  | 
 | ||||||
| struct PollFD { | struct PollFD { | ||||||
|     s32 fd; |     s32 fd; | ||||||
|     u16 events; |     PollEvents events; | ||||||
|     u16 revents; |     PollEvents revents; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Linger { | struct Linger { | ||||||
|  | @ -80,13 +92,6 @@ struct Linger { | ||||||
|     u32 linger; |     u32 linger; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| constexpr u16 POLL_IN = 0x01; |  | ||||||
| constexpr u16 POLL_PRI = 0x02; |  | ||||||
| constexpr u16 POLL_OUT = 0x04; |  | ||||||
| constexpr u16 POLL_ERR = 0x08; |  | ||||||
| constexpr u16 POLL_HUP = 0x10; |  | ||||||
| constexpr u16 POLL_NVAL = 0x20; |  | ||||||
| 
 |  | ||||||
| constexpr u32 FLAG_MSG_DONTWAIT = 0x80; | constexpr u32 FLAG_MSG_DONTWAIT = 0x80; | ||||||
| 
 | 
 | ||||||
| constexpr u32 FLAG_O_NONBLOCK = 0x800; | constexpr u32 FLAG_O_NONBLOCK = 0x800; | ||||||
|  |  | ||||||
|  | @ -89,43 +89,43 @@ Network::Protocol Translate(Type type, Protocol protocol) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 TranslatePollEventsToHost(u32 flags) { | Network::PollEvents TranslatePollEventsToHost(PollEvents flags) { | ||||||
|     u32 result = 0; |     Network::PollEvents result{}; | ||||||
|     const auto translate = [&result, &flags](u32 from, u32 to) { |     const auto translate = [&result, &flags](PollEvents from, Network::PollEvents to) { | ||||||
|         if ((flags & from) != 0) { |         if (True(flags & from)) { | ||||||
|             flags &= ~from; |             flags &= ~from; | ||||||
|             result |= to; |             result |= to; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     translate(POLL_IN, Network::POLL_IN); |     translate(PollEvents::In, Network::PollEvents::In); | ||||||
|     translate(POLL_PRI, Network::POLL_PRI); |     translate(PollEvents::Pri, Network::PollEvents::Pri); | ||||||
|     translate(POLL_OUT, Network::POLL_OUT); |     translate(PollEvents::Out, Network::PollEvents::Out); | ||||||
|     translate(POLL_ERR, Network::POLL_ERR); |     translate(PollEvents::Err, Network::PollEvents::Err); | ||||||
|     translate(POLL_HUP, Network::POLL_HUP); |     translate(PollEvents::Hup, Network::PollEvents::Hup); | ||||||
|     translate(POLL_NVAL, Network::POLL_NVAL); |     translate(PollEvents::Nval, Network::PollEvents::Nval); | ||||||
| 
 | 
 | ||||||
|     UNIMPLEMENTED_IF_MSG(flags != 0, "Unimplemented flags={}", flags); |     UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags); | ||||||
|     return static_cast<u16>(result); |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 TranslatePollEventsToGuest(u32 flags) { | PollEvents TranslatePollEventsToGuest(Network::PollEvents flags) { | ||||||
|     u32 result = 0; |     PollEvents result{}; | ||||||
|     const auto translate = [&result, &flags](u32 from, u32 to) { |     const auto translate = [&result, &flags](Network::PollEvents from, PollEvents to) { | ||||||
|         if ((flags & from) != 0) { |         if (True(flags & from)) { | ||||||
|             flags &= ~from; |             flags &= ~from; | ||||||
|             result |= to; |             result |= to; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     translate(Network::POLL_IN, POLL_IN); |     translate(Network::PollEvents::In, PollEvents::In); | ||||||
|     translate(Network::POLL_PRI, POLL_PRI); |     translate(Network::PollEvents::Pri, PollEvents::Pri); | ||||||
|     translate(Network::POLL_OUT, POLL_OUT); |     translate(Network::PollEvents::Out, PollEvents::Out); | ||||||
|     translate(Network::POLL_ERR, POLL_ERR); |     translate(Network::PollEvents::Err, PollEvents::Err); | ||||||
|     translate(Network::POLL_HUP, POLL_HUP); |     translate(Network::PollEvents::Hup, PollEvents::Hup); | ||||||
|     translate(Network::POLL_NVAL, POLL_NVAL); |     translate(Network::PollEvents::Nval, PollEvents::Nval); | ||||||
| 
 | 
 | ||||||
|     UNIMPLEMENTED_IF_MSG(flags != 0, "Unimplemented flags={}", flags); |     UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags); | ||||||
|     return static_cast<u16>(result); |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Network::SockAddrIn Translate(SockAddrIn value) { | Network::SockAddrIn Translate(SockAddrIn value) { | ||||||
|  |  | ||||||
|  | @ -31,10 +31,10 @@ Network::Type Translate(Type type); | ||||||
| Network::Protocol Translate(Type type, Protocol protocol); | Network::Protocol Translate(Type type, Protocol protocol); | ||||||
| 
 | 
 | ||||||
| /// Translate abstract poll event flags to guest poll event flags
 | /// Translate abstract poll event flags to guest poll event flags
 | ||||||
| u16 TranslatePollEventsToHost(u32 flags); | Network::PollEvents TranslatePollEventsToHost(PollEvents flags); | ||||||
| 
 | 
 | ||||||
| /// Translate guest poll event flags to abstract poll event flags
 | /// Translate guest poll event flags to abstract poll event flags
 | ||||||
| u16 TranslatePollEventsToGuest(u32 flags); | PollEvents TranslatePollEventsToGuest(Network::PollEvents flags); | ||||||
| 
 | 
 | ||||||
| /// Translate guest socket address structure to abstract socket address structure
 | /// Translate guest socket address structure to abstract socket address structure
 | ||||||
| Network::SockAddrIn Translate(SockAddrIn value); | Network::SockAddrIn Translate(SockAddrIn value); | ||||||
|  |  | ||||||
|  | @ -238,49 +238,49 @@ SockAddrIn TranslateToSockAddrIn(sockaddr input_) { | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 TranslatePollEvents(u32 events) { | short TranslatePollEvents(PollEvents events) { | ||||||
|     u32 result = 0; |     short result = 0; | ||||||
| 
 | 
 | ||||||
|     if ((events & POLL_IN) != 0) { |     if (True(events & PollEvents::In)) { | ||||||
|         events &= ~POLL_IN; |         events &= ~PollEvents::In; | ||||||
|         result |= POLLIN; |         result |= POLLIN; | ||||||
|     } |     } | ||||||
|     if ((events & POLL_PRI) != 0) { |     if (True(events & PollEvents::Pri)) { | ||||||
|         events &= ~POLL_PRI; |         events &= ~PollEvents::Pri; | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
|         LOG_WARNING(Service, "Winsock doesn't support POLLPRI"); |         LOG_WARNING(Service, "Winsock doesn't support POLLPRI"); | ||||||
| #else | #else | ||||||
|         result |= POLL_PRI; |         result |= POLLPRI; | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
|     if ((events & POLL_OUT) != 0) { |     if (True(events & PollEvents::Out)) { | ||||||
|         events &= ~POLL_OUT; |         events &= ~PollEvents::Out; | ||||||
|         result |= POLLOUT; |         result |= POLLOUT; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     UNIMPLEMENTED_IF_MSG(events != 0, "Unhandled guest events=0x{:x}", events); |     UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events=0x{:x}", (u16)events); | ||||||
| 
 | 
 | ||||||
|     return static_cast<u16>(result); |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 TranslatePollRevents(u32 revents) { | PollEvents TranslatePollRevents(short revents) { | ||||||
|     u32 result = 0; |     PollEvents result{}; | ||||||
|     const auto translate = [&result, &revents](u32 host, u32 guest) { |     const auto translate = [&result, &revents](short host, PollEvents guest) { | ||||||
|         if ((revents & host) != 0) { |         if ((revents & host) != 0) { | ||||||
|             revents &= ~host; |             revents &= static_cast<short>(~host); | ||||||
|             result |= guest; |             result |= guest; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     translate(POLLIN, POLL_IN); |     translate(POLLIN, PollEvents::In); | ||||||
|     translate(POLLPRI, POLL_PRI); |     translate(POLLPRI, PollEvents::Pri); | ||||||
|     translate(POLLOUT, POLL_OUT); |     translate(POLLOUT, PollEvents::Out); | ||||||
|     translate(POLLERR, POLL_ERR); |     translate(POLLERR, PollEvents::Err); | ||||||
|     translate(POLLHUP, POLL_HUP); |     translate(POLLHUP, PollEvents::Hup); | ||||||
| 
 | 
 | ||||||
|     UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents); |     UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents); | ||||||
| 
 | 
 | ||||||
|     return static_cast<u16>(result); |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
|  | @ -350,7 +350,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < num; ++i) { |     for (size_t i = 0; i < num; ++i) { | ||||||
|         pollfds[i].revents = TranslatePollRevents(static_cast<u32>(host_pollfds[i].revents)); |         pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (result > 0) { |     if (result > 0) { | ||||||
|  |  | ||||||
|  | @ -61,18 +61,24 @@ struct SockAddrIn { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// Cross-platform poll fd structure
 | /// Cross-platform poll fd structure
 | ||||||
| struct PollFD { | 
 | ||||||
|     Socket* socket; | enum class PollEvents : u16 { | ||||||
|     u16 events; |     // Using Pascal case because IN is a macro on Windows.
 | ||||||
|     u16 revents; |     In = 1 << 0, | ||||||
|  |     Pri = 1 << 1, | ||||||
|  |     Out = 1 << 2, | ||||||
|  |     Err = 1 << 3, | ||||||
|  |     Hup = 1 << 4, | ||||||
|  |     Nval = 1 << 5, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| constexpr u16 POLL_IN = 1 << 0; | DECLARE_ENUM_FLAG_OPERATORS(PollEvents); | ||||||
| constexpr u16 POLL_PRI = 1 << 1; | 
 | ||||||
| constexpr u16 POLL_OUT = 1 << 2; | struct PollFD { | ||||||
| constexpr u16 POLL_ERR = 1 << 3; |     Socket* socket; | ||||||
| constexpr u16 POLL_HUP = 1 << 4; |     PollEvents events; | ||||||
| constexpr u16 POLL_NVAL = 1 << 5; |     PollEvents revents; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| class NetworkInstance { | class NetworkInstance { | ||||||
| public: | public: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 comex
						comex