+/* Look up the node with same fd and wevent. */
+static struct poll_node *
+find_poll_node(struct poll_loop *loop, int fd, HANDLE wevent)
+{
+ struct poll_node *node;
+
+ HMAP_FOR_EACH_WITH_HASH (node, hmap_node,
+ hash_2words(fd, (uint32_t)wevent),
+ &loop->poll_nodes) {
+ if (node->pollfd.fd == fd && node->wevent == wevent) {
+ return node;
+ }
+ }
+ return NULL;
+}
+
+/* On Unix based systems:
+ *
+ * Registers 'fd' as waiting for the specified 'events' (which should be
+ * POLLIN or POLLOUT or POLLIN | POLLOUT). The following call to
+ * poll_block() will wake up when 'fd' becomes ready for one or more of the
+ * requested events. The 'fd's are given to poll() function later.
+ *
+ * On Windows system:
+ *
+ * If 'fd' is specified, create a new 'wevent'. Association of 'fd' and
+ * 'wevent' for 'events' happens in poll_block(). If 'wevent' is specified,
+ * it is assumed that it is unrelated to any sockets and poll_block()
+ * will wake up on any event on that 'wevent'. It is an error to pass
+ * both 'wevent' and 'fd'.
+ *
+ * The event registration is one-shot: only the following call to
+ * poll_block() is affected. The event will need to be re-registered after
+ * poll_block() is called if it is to persist.
+ *
+ * ('where' is used in debug logging. Commonly one would use poll_fd_wait() to
+ * automatically provide the caller's source file and line number for
+ * 'where'.) */
+static void
+poll_create_node(int fd, HANDLE wevent, short int events, const char *where)
+{
+ struct poll_loop *loop = poll_loop();
+ struct poll_node *node;
+
+ COVERAGE_INC(poll_create_node);
+
+ /* Both 'fd' and 'wevent' cannot be set. */
+ ovs_assert(!fd != !wevent);
+
+ /* Check for duplicate. If found, "or" the events. */
+ node = find_poll_node(loop, fd, wevent);
+ if (node) {
+ node->pollfd.events |= events;
+ } else {
+ node = xzalloc(sizeof *node);
+ hmap_insert(&loop->poll_nodes, &node->hmap_node,
+ hash_2words(fd, (uint32_t)wevent));
+ node->pollfd.fd = fd;
+ node->pollfd.events = events;
+#ifdef _WIN32
+ if (!wevent) {
+ wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ }
+#endif
+ node->wevent = wevent;
+ node->where = where;
+ }
+}
+