VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NAT/RTWinPoll.cpp@ 49983

Last change on this file since 49983 was 48956, checked in by vboxsync, 11 years ago

NetworkServices: Whitespace (including tabs!) and svn:keywords cleanups by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1/* -*- indent-tabs-mode: nil; -*- */
2#include <iprt/asm.h>
3#include <iprt/assert.h>
4#include <iprt/cdefs.h>
5#include <iprt/err.h>
6#include <iprt/string.h>
7
8#include <VBox/err.h>
9
10#include <Winsock2.h>
11#include <Windows.h>
12#include "winpoll.h"
13
14static HANDLE g_hNetworkEvent;
15
16int
17RTWinPoll(struct pollfd *pFds, unsigned int nfds, int timeout, int *pNready)
18{
19 AssertPtrReturn(pFds, VERR_INVALID_PARAMETER);
20
21 if (g_hNetworkEvent == WSA_INVALID_EVENT)
22 {
23 g_hNetworkEvent = WSACreateEvent();
24 AssertReturn(g_hNetworkEvent != WSA_INVALID_EVENT, VERR_INTERNAL_ERROR);
25 }
26
27 for (unsigned int i = 0; i < nfds; ++i)
28 {
29 long eventMask = 0;
30 short pollEvents = pFds[i].events;
31
32 /* clean revents */
33 pFds[i].revents = 0;
34
35 /* ignore invalid sockets */
36 if (pFds[i].fd == INVALID_SOCKET)
37 continue;
38
39 /**
40 * POLLIN Data other than high priority data may be read without blocking.
41 * This is equivalent to ( POLLRDNORM | POLLRDBAND ).
42 * POLLRDBAND Priority data may be read without blocking.
43 * POLLRDNORM Normal data may be read without blocking.
44 */
45 if (pollEvents & POLLIN)
46 eventMask |= FD_READ | FD_ACCEPT;
47
48 /**
49 * POLLOUT Normal data may be written without blocking. This is equivalent
50 * to POLLWRNORM.
51 * POLLWRNORM Normal data may be written without blocking.
52 */
53 if (pollEvents & POLLOUT)
54 eventMask |= FD_WRITE | FD_CONNECT;
55
56 /**
57 * This is "moral" equivalent to POLLHUP.
58 */
59 eventMask |= FD_CLOSE;
60 WSAEventSelect(pFds[i].fd, g_hNetworkEvent, eventMask);
61 }
62
63 DWORD index = WSAWaitForMultipleEvents(1,
64 &g_hNetworkEvent,
65 FALSE,
66 timeout == RT_INDEFINITE_WAIT ? WSA_INFINITE : timeout,
67 FALSE);
68 if (index != WSA_WAIT_EVENT_0)
69 {
70 if (index == WSA_WAIT_TIMEOUT)
71 return VERR_TIMEOUT;
72 }
73
74 int nready = 0;
75 for (unsigned int i = 0; i < nfds; ++i)
76 {
77 short revents = 0;
78 WSANETWORKEVENTS NetworkEvents;
79 int err;
80
81 if (pFds[i].fd == INVALID_SOCKET)
82 continue;
83
84 RT_ZERO(NetworkEvents);
85
86 err = WSAEnumNetworkEvents(pFds[i].fd,
87 g_hNetworkEvent,
88 &NetworkEvents);
89
90 if (err == SOCKET_ERROR)
91 {
92 if (WSAGetLastError() == WSAENOTSOCK)
93 {
94 pFds[i].revents = POLLNVAL;
95 ++nready;
96 }
97 continue;
98 }
99
100 /* deassociate socket with event */
101 WSAEventSelect(pFds[i].fd, g_hNetworkEvent, 0);
102
103 if (NetworkEvents.lNetworkEvents & (FD_READ|FD_ACCEPT))
104 {
105 if ( NetworkEvents.iErrorCode[FD_READ_BIT] != 0
106 || NetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
107 revents |= POLLERR;
108
109 revents |= POLLIN;
110 }
111
112 if (NetworkEvents.lNetworkEvents & (FD_WRITE|FD_CONNECT))
113 {
114 if ( NetworkEvents.iErrorCode[FD_WRITE_BIT] != 0
115 || NetworkEvents.iErrorCode[FD_CONNECT_BIT] != 0)
116 revents |= POLLERR;
117
118 revents |= POLLOUT;
119 }
120
121 if (NetworkEvents.lNetworkEvents & FD_CLOSE)
122 {
123 if (NetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
124 revents |= POLLERR;
125
126 revents |= POLLHUP;
127 }
128
129 /* paranoid */
130 revents &= (pFds[i].events | POLLHUP | POLLERR);
131 if (revents != 0)
132 {
133 pFds[i].revents = revents;
134 ++nready;
135 }
136 }
137 WSAResetEvent(g_hNetworkEvent);
138
139 if (pNready)
140 *pNready = nready;
141
142 return VINF_SUCCESS;
143}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette