net: fix Linux select fdwatch readiness
Some checks failed
build / Main build job (push) Has been cancelled
Some checks failed
build / Main build job (push) Has been cancelled
This commit is contained in:
@@ -309,6 +309,20 @@ static int fdwatch_get_fdidx(LPFDWATCH fdw, socket_t fd) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fdwatch_get_maxfd(LPFDWATCH fdw)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
socket_t max_fd = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < fdw->nselect_fds; ++i)
|
||||||
|
{
|
||||||
|
if (fdw->select_fds[i] > max_fd)
|
||||||
|
max_fd = fdw->select_fds[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int>(max_fd) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot)
|
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot)
|
||||||
{
|
{
|
||||||
int idx = fdwatch_get_fdidx(fdw, fd);
|
int idx = fdwatch_get_fdidx(fdw, fd);
|
||||||
@@ -318,10 +332,13 @@ void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int o
|
|||||||
}
|
}
|
||||||
idx = fdw->nselect_fds;
|
idx = fdw->nselect_fds;
|
||||||
fdw->select_fds[fdw->nselect_fds++] = fd;
|
fdw->select_fds[fdw->nselect_fds++] = fd;
|
||||||
fdw->fd_rw[idx] = rw;
|
fdw->fd_rw[idx] = 0;
|
||||||
} else {
|
|
||||||
fdw->fd_rw[idx] |= rw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fdw->fd_rw[idx] |= rw;
|
||||||
|
if (oneshot && (rw & FDW_WRITE))
|
||||||
|
fdw->fd_rw[idx] |= FDW_WRITE_ONESHOT;
|
||||||
|
|
||||||
fdw->fd_data[idx] = client_data;
|
fdw->fd_data[idx] = client_data;
|
||||||
|
|
||||||
if (rw & FDW_READ)
|
if (rw & FDW_READ)
|
||||||
@@ -354,6 +371,7 @@ void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd)
|
|||||||
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
|
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
|
||||||
{
|
{
|
||||||
int r, i, event_idx;
|
int r, i, event_idx;
|
||||||
|
int max_fd = fdwatch_get_maxfd(fdw);
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
fdw->working_rfd_set = fdw->rfd_set;
|
fdw->working_rfd_set = fdw->rfd_set;
|
||||||
@@ -363,12 +381,12 @@ int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
|
|||||||
{
|
{
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
r = select(max_fd, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tv = *timeout;
|
tv = *timeout;
|
||||||
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
r = select(max_fd, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
@@ -404,7 +422,7 @@ int fdwatch_check_fd(LPFDWATCH fdw, socket_t fd)
|
|||||||
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
|
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
|
||||||
{
|
{
|
||||||
int idx = fdw->select_rfdidx[event_idx];
|
int idx = fdw->select_rfdidx[event_idx];
|
||||||
if (idx < 0 || fdw->nfiles <= idx) {
|
if (idx < 0 || fdw->nselect_fds <= idx) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return fdw->fd_data[idx];
|
return fdw->fd_data[idx];
|
||||||
@@ -413,7 +431,7 @@ void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
|
|||||||
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
|
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
|
||||||
{
|
{
|
||||||
int idx = fdw->select_rfdidx[event_idx];
|
int idx = fdw->select_rfdidx[event_idx];
|
||||||
if (idx < 0 || fdw->nfiles <= idx) {
|
if (idx < 0 || fdw->nselect_fds <= idx) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (int)fdw->select_fds[idx];
|
return (int)fdw->select_fds[idx];
|
||||||
@@ -422,7 +440,7 @@ int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
|
|||||||
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||||
{
|
{
|
||||||
int idx = fdw->select_rfdidx[event_idx];
|
int idx = fdw->select_rfdidx[event_idx];
|
||||||
if (idx < 0 || fdw->nfiles <= idx) {
|
if (idx < 0 || fdw->nselect_fds <= idx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
socket_t rfd = fdw->select_fds[idx];
|
socket_t rfd = fdw->select_fds[idx];
|
||||||
@@ -436,7 +454,7 @@ void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
|||||||
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||||
{
|
{
|
||||||
int idx = fdw->select_rfdidx[event_idx];
|
int idx = fdw->select_rfdidx[event_idx];
|
||||||
if (idx < 0 || fdw->nfiles <= idx) {
|
if (idx < 0 || fdw->nselect_fds <= idx) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
socket_t rfd = fdw->select_fds[idx];
|
socket_t rfd = fdw->select_fds[idx];
|
||||||
@@ -447,6 +465,11 @@ int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
|||||||
if (result & FDW_READ) {
|
if (result & FDW_READ) {
|
||||||
return FDW_READ;
|
return FDW_READ;
|
||||||
} else if (result & FDW_WRITE) {
|
} else if (result & FDW_WRITE) {
|
||||||
|
if (fdw->fd_rw[idx] & FDW_WRITE_ONESHOT) {
|
||||||
|
fdw->fd_rw[idx] &= ~(FDW_WRITE | FDW_WRITE_ONESHOT);
|
||||||
|
FD_CLR(fd, &fdw->wfd_set);
|
||||||
|
FD_CLR(fd, &fdw->working_wfd_set);
|
||||||
|
}
|
||||||
return FDW_WRITE;
|
return FDW_WRITE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user