TcpSocket: Update NetworkWaiter to Subscriber Model

Had a clever idea over the weekend. Was just going to write up some
pseudocode to get an idea if it would work, and ended up with a fully
working solution

In order for TcpConnections to be initialized on posix systems, we need
to use accept, as documented here:
    http://man7.org/linux/man-pages/man2/accept.2.html

Accept uses a polling mechanism, similar to UdpSocket Reads.
Additionally, according to the above documentation, we can use Select to
check if the socket is ready to connect, as documented here:
    http://man7.org/linux/man-pages/man2/select.2.html

Because this same mechanism is already used for UdpSocket Reads in the
NetworkReader (via the NetworkWaiter class), we can repurpose the
existing NetworkWaiter to work for both its current NetworkReader use
and a new TcpConnectionReader (name pending) class (in the next CL)

The next step in doing so is to change NetworkWaiter to a subscriber
model, so it can pull the FDs to process instead of pushing them. This
will allow multiple subscribers to provide FDs while only requiring one
networking thread to process them.

Change-Id: I5cfeaec517f20dbf8f1b79224a950a19828c5c75
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1791373
Commit-Queue: Ryan Keane <rwkeane@google.com>
Reviewed-by: Max Yakimakha <yakimakha@chromium.org>
Reviewed-by: Yuri Wiitala <miu@chromium.org>
diff --git a/platform/impl/socket_handle.h b/platform/impl/socket_handle.h
index 9aea5f1..6a775f1 100644
--- a/platform/impl/socket_handle.h
+++ b/platform/impl/socket_handle.h
@@ -5,6 +5,8 @@
 #ifndef PLATFORM_IMPL_SOCKET_HANDLE_H_
 #define PLATFORM_IMPL_SOCKET_HANDLE_H_
 
+#include <cstdlib>
+
 namespace openscreen {
 namespace platform {
 
@@ -12,6 +14,15 @@
 // platform.
 struct SocketHandle;
 
+struct SocketHandleHash {
+  size_t operator()(const SocketHandle& handle) const;
+};
+
+bool operator==(const SocketHandle& lhs, const SocketHandle& rhs);
+inline bool operator!=(const SocketHandle& lhs, const SocketHandle& rhs) {
+  return !(lhs == rhs);
+}
+
 }  // namespace platform
 }  // namespace openscreen