I'm using WSAPoll for my project. I used tracking POLLIN and POLLOUT events. Everything worked nice. When I add POLLHUP as event, WSAPoll returns error 10022 (Invalid argument).
I've no idea what's wrong, please guide me how to fix it:(
cc_qnt
- quantity of connected clients
int ev_cnt = WSAPoll(pfd, cc_qnt + 1, 100);
if (ev_cnt > 0) {
for (i = 0; i < cc_qnt; i++) {
if (pfd[i].revents & POLLHUP) {
// some code
}
if (pfd[i].revents & POLLIN) {
// some code
}
}
if (pfd[cc_qnt].revents & POLLIN) {
In this part we have new connection ready for accepting. We edit pfd[cc_qnt]
adding new socket (returned by accept) instead of listening socket. Then we reallocate pfd with size + 1, copying previous data and adding listening socket at the end of cc array.
int addrlen = sizeof(addr);
cc[cc_qnt].s = accept(ls, (struct sockaddr*) &addr, &addrlen);
cc[cc_qnt].ip = ntohl(addr.sin_addr.s_addr);
cc[cc_qnt].sent_put = 0;
cc[cc_qnt].c_cl_cn = 0;
pfd[cc_qnt].fd = cc[i].s;
pfd[cc_qnt].events = POLLIN | POLLOUT | POLLHUP;
cc_qnt++;
pfd = init_pfd(pfd, ls, cc_qnt);
}
}
else if (ev_cnt < 0) {
exit(printf("\nprocess_events: WSAPoll, ev_cnt = %d, WSAGetLastError: %d \n", ev_cnt, WSAGetLastError()));
}
Everything I changed for tracking POLLHUP - adding it's bit to pfd[cc_qnt].events and WSAPoll started returning error. I expect tracking POLLHUP event.
Per the WSAPoll()
documentation:
WSAEINVAL
An invalid parameter was passed. This error is returned if the
fdarray
parameter contains aNULL
pointer. This error is also returned if invalid flags were specified in theevents
member of any of theWSAPOLLFD
structures pointed to by thefdarray
parameter when requesting socket status. This error is also returned if none of the sockets specified in thefd
member of any of theWSAPOLLFD
structures pointed to by thefdarray
parameter were valid.
And per the WSAPOLLFD
documentation:
events
Type:
short
A set of flags indicating the type of status being requested. This must be one or more of the following.
POLLPRI
Priority data may be read without blocking. This flag is not supported by the Microsoft Winsock provider.
POLLRDBAND
Priority band (out-of-band) data can be read without blocking.
POLLRDNORM
Normal data can be read without blocking.
POLLWRNORM
Normal data can be written without blocking.The
POLLIN
flag is defined as the combination of thePOLLRDNORM
andPOLLRDBAND
flag values. ThePOLLOUT
flag is defined as the same as thePOLLWRNORM
flag value.
So, as you can see, POLLHUP
is not documented as being a valid flag for input to WSAPoll()
. Indeed, it does not match any of the above flags defined in winsock2.h
:
/* Event flag definitions for WSAPoll(). */
#define POLLRDNORM 0x0100
#define POLLRDBAND 0x0200
#define POLLIN (POLLRDNORM | POLLRDBAND)
#define POLLPRI 0x0400
#define POLLWRNORM 0x0010
#define POLLOUT (POLLWRNORM)
#define POLLWRBAND 0x0020
#define POLLERR 0x0001
#define POLLHUP 0x0002
#define POLLNVAL 0x0004
POLLHUP
is, however, documented as an output flag in the revents
member of WSAPOLLFD
:
revents
Type:
short
A set of flags that indicate, upon return from the WSAPoll function call, the results of the status query. This can a combination of the following flags.
...
POLLHUP
A stream-oriented connection was either disconnected or aborted....
This matches the use of POLLHUP
in poll()
on *nix platforms:
POLLHUP
Hang up (only returned inrevents
; ignored inevents
). Note that when reading from a channel such as a pipe or a stream socket, this event merely indicates that the peer closed its end of the channel. Subsequent reads from the channel will return 0 (end of file) only after all outstanding data in the channel has been consumed.
So, you don't need to (and on Windows, you cannot) explicitly request POLLHUP
, you just get it for free.