mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-24 23:25:58 +00:00
Slightly rework the fix for bug #51990: allocate select_cb only if we actually need to wait
This commit is contained in:
parent
72a00ca79c
commit
92b6f83eb2
@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name)
|
#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name)
|
||||||
#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name)
|
#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name)
|
||||||
#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock)
|
#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock)
|
||||||
#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name)
|
#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name)
|
||||||
|
|
||||||
#if LWIP_IPV4
|
#if LWIP_IPV4
|
||||||
@ -1844,7 +1844,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
int nready;
|
int nready;
|
||||||
fd_set lreadset, lwriteset, lexceptset;
|
fd_set lreadset, lwriteset, lexceptset;
|
||||||
u32_t msectimeout;
|
u32_t msectimeout;
|
||||||
API_SELECT_CB_VAR_DECLARE(select_cb);
|
|
||||||
int i;
|
int i;
|
||||||
int maxfdp2;
|
int maxfdp2;
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
@ -1856,8 +1855,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
SYS_ARCH_DECL_PROTECT(lev);
|
SYS_ARCH_DECL_PROTECT(lev);
|
||||||
LWIP_SOCKET_SELECT_DECL_PROTECT(lev2);
|
LWIP_SOCKET_SELECT_DECL_PROTECT(lev2);
|
||||||
|
|
||||||
API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); return -1);
|
|
||||||
|
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
|
||||||
maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
|
maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
|
||||||
timeout ? (s32_t)timeout->tv_sec : (s32_t)-1,
|
timeout ? (s32_t)timeout->tv_sec : (s32_t)-1,
|
||||||
@ -1865,7 +1862,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
|
|
||||||
if ((maxfdp1 < 0) || (maxfdp1 > (FD_SETSIZE + LWIP_SOCKET_OFFSET))) {
|
if ((maxfdp1 < 0) || (maxfdp1 > (FD_SETSIZE + LWIP_SOCKET_OFFSET))) {
|
||||||
set_errno(EINVAL);
|
set_errno(EINVAL);
|
||||||
API_SELECT_CB_VAR_FREE(select_cb);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1876,192 +1872,194 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
||||||
|
|
||||||
if (nready < 0) {
|
if (nready < 0) {
|
||||||
|
/* one of the sockets in one of the fd_sets was invalid */
|
||||||
set_errno(EBADF);
|
set_errno(EBADF);
|
||||||
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
||||||
API_SELECT_CB_VAR_FREE(select_cb);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (nready > 0) {
|
||||||
|
/* one or more sockets are set, no need to wait */
|
||||||
/* If we don't have any current events, then suspend if we are supposed to */
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
|
||||||
if (!nready) {
|
} else {
|
||||||
|
/* If we don't have any current events, then suspend if we are supposed to */
|
||||||
if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
|
if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
|
||||||
/* This is OK as the local fdsets are empty and nready is zero,
|
/* This is OK as the local fdsets are empty and nready is zero,
|
||||||
or we would have returned earlier. */
|
or we would have returned earlier. */
|
||||||
goto return_copy_fdsets;
|
} else {
|
||||||
}
|
/* None ready: add our semaphore to list:
|
||||||
|
We don't actually need any dynamic memory. Our entry on the
|
||||||
|
list is only valid while we are in this function, so it's ok
|
||||||
|
to use local variables (unless we're running in MPU compatible
|
||||||
|
mode). */
|
||||||
|
API_SELECT_CB_VAR_DECLARE(select_cb);
|
||||||
|
API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); return -1);
|
||||||
|
|
||||||
/* None ready: add our semaphore to list:
|
API_SELECT_CB_VAR_REF(select_cb).next = NULL;
|
||||||
We don't actually need any dynamic memory. Our entry on the
|
API_SELECT_CB_VAR_REF(select_cb).prev = NULL;
|
||||||
list is only valid while we are in this function, so it's ok
|
API_SELECT_CB_VAR_REF(select_cb).readset = readset;
|
||||||
to use local variables. */
|
API_SELECT_CB_VAR_REF(select_cb).writeset = writeset;
|
||||||
|
API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset;
|
||||||
API_SELECT_CB_VAR_REF(select_cb).next = NULL;
|
API_SELECT_CB_VAR_REF(select_cb).sem_signalled = 0;
|
||||||
API_SELECT_CB_VAR_REF(select_cb).prev = NULL;
|
|
||||||
API_SELECT_CB_VAR_REF(select_cb).readset = readset;
|
|
||||||
API_SELECT_CB_VAR_REF(select_cb).writeset = writeset;
|
|
||||||
API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset;
|
|
||||||
API_SELECT_CB_VAR_REF(select_cb).sem_signalled = 0;
|
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET();
|
API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||||
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||||
if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) {
|
if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) {
|
||||||
/* failed to create semaphore */
|
/* failed to create semaphore */
|
||||||
set_errno(ENOMEM);
|
set_errno(ENOMEM);
|
||||||
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
||||||
API_SELECT_CB_VAR_FREE(select_cb);
|
API_SELECT_CB_VAR_FREE(select_cb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||||
|
|
||||||
/* Protect the select_cb_list */
|
/* Protect the select_cb_list */
|
||||||
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
||||||
|
|
||||||
/* Put this select_cb on top of list */
|
/* Put this select_cb on top of list */
|
||||||
API_SELECT_CB_VAR_REF(select_cb).next = select_cb_list;
|
API_SELECT_CB_VAR_REF(select_cb).next = select_cb_list;
|
||||||
if (select_cb_list != NULL) {
|
if (select_cb_list != NULL) {
|
||||||
select_cb_list->prev = &API_SELECT_CB_VAR_REF(select_cb);
|
select_cb_list->prev = &API_SELECT_CB_VAR_REF(select_cb);
|
||||||
}
|
}
|
||||||
select_cb_list = &API_SELECT_CB_VAR_REF(select_cb);
|
select_cb_list = &API_SELECT_CB_VAR_REF(select_cb);
|
||||||
#if !LWIP_TCPIP_CORE_LOCKING
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
/* Increasing this counter tells select_check_waiters that the list has changed. */
|
/* Increasing this counter tells select_check_waiters that the list has changed. */
|
||||||
select_cb_ctr++;
|
select_cb_ctr++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Now we can safely unprotect */
|
/* Now we can safely unprotect */
|
||||||
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
||||||
|
|
||||||
/* Increase select_waiting for each socket we are interested in */
|
/* Increase select_waiting for each socket we are interested in */
|
||||||
maxfdp2 = maxfdp1;
|
maxfdp2 = maxfdp1;
|
||||||
for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) {
|
for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) {
|
||||||
if ((readset && FD_ISSET(i, readset)) ||
|
if ((readset && FD_ISSET(i, readset)) ||
|
||||||
(writeset && FD_ISSET(i, writeset)) ||
|
(writeset && FD_ISSET(i, writeset)) ||
|
||||||
(exceptset && FD_ISSET(i, exceptset))) {
|
(exceptset && FD_ISSET(i, exceptset))) {
|
||||||
struct lwip_sock *sock;
|
struct lwip_sock *sock;
|
||||||
SYS_ARCH_PROTECT(lev);
|
SYS_ARCH_PROTECT(lev);
|
||||||
sock = tryget_socket_unconn(i);
|
sock = tryget_socket_unconn(i);
|
||||||
if (sock != NULL) {
|
if (sock != NULL) {
|
||||||
sock->select_waiting++;
|
sock->select_waiting++;
|
||||||
if (sock->select_waiting == 0) {
|
if (sock->select_waiting == 0) {
|
||||||
/* overflow - too many threads waiting */
|
/* overflow - too many threads waiting */
|
||||||
sock->select_waiting--;
|
sock->select_waiting--;
|
||||||
|
done_socket(sock);
|
||||||
|
nready = -1;
|
||||||
|
maxfdp2 = i;
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
set_errno(EBUSY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
done_socket(sock);
|
done_socket(sock);
|
||||||
|
} else {
|
||||||
|
/* Not a valid socket */
|
||||||
nready = -1;
|
nready = -1;
|
||||||
maxfdp2 = i;
|
maxfdp2 = i;
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
set_errno(EBUSY);
|
set_errno(EBADF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done_socket(sock);
|
|
||||||
} else {
|
|
||||||
/* Not a valid socket */
|
|
||||||
nready = -1;
|
|
||||||
maxfdp2 = i;
|
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
set_errno(EBADF);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (nready >= 0) {
|
if (nready >= 0) {
|
||||||
/* Call lwip_selscan again: there could have been events between
|
/* Call lwip_selscan again: there could have been events between
|
||||||
the last scan (without us on the list) and putting us on the list! */
|
the last scan (without us on the list) and putting us on the list! */
|
||||||
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
||||||
if (!nready) {
|
if (!nready) {
|
||||||
/* Still none ready, just wait to be woken */
|
/* Still none ready, just wait to be woken */
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
/* Wait forever */
|
/* Wait forever */
|
||||||
msectimeout = 0;
|
msectimeout = 0;
|
||||||
} else {
|
|
||||||
long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
|
|
||||||
if (msecs_long <= 0) {
|
|
||||||
/* Wait 1ms at least (0 means wait forever) */
|
|
||||||
msectimeout = 1;
|
|
||||||
} else {
|
} else {
|
||||||
msectimeout = (u32_t)msecs_long;
|
long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
|
||||||
|
if (msecs_long <= 0) {
|
||||||
|
/* Wait 1ms at least (0 means wait forever) */
|
||||||
|
msectimeout = 1;
|
||||||
|
} else {
|
||||||
|
msectimeout = (u32_t)msecs_long;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
|
waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
waited = 1;
|
waited = 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrease select_waiting for each socket we are interested in */
|
|
||||||
for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) {
|
|
||||||
if ((readset && FD_ISSET(i, readset)) ||
|
|
||||||
(writeset && FD_ISSET(i, writeset)) ||
|
|
||||||
(exceptset && FD_ISSET(i, exceptset))) {
|
|
||||||
struct lwip_sock *sock;
|
|
||||||
SYS_ARCH_PROTECT(lev);
|
|
||||||
sock = tryget_socket_unconn(i);
|
|
||||||
if (sock != NULL) {
|
|
||||||
/* for now, handle select_waiting==0... */
|
|
||||||
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
|
|
||||||
if (sock->select_waiting > 0) {
|
|
||||||
sock->select_waiting--;
|
|
||||||
}
|
|
||||||
done_socket(sock);
|
|
||||||
} else {
|
|
||||||
/* Not a valid socket */
|
|
||||||
nready = -1;
|
|
||||||
set_errno(EBADF);
|
|
||||||
}
|
}
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Take us off the list */
|
/* Decrease select_waiting for each socket we are interested in */
|
||||||
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) {
|
||||||
if (API_SELECT_CB_VAR_REF(select_cb).next != NULL) {
|
if ((readset && FD_ISSET(i, readset)) ||
|
||||||
API_SELECT_CB_VAR_REF(select_cb).next->prev = API_SELECT_CB_VAR_REF(select_cb).prev;
|
(writeset && FD_ISSET(i, writeset)) ||
|
||||||
}
|
(exceptset && FD_ISSET(i, exceptset))) {
|
||||||
if (select_cb_list == &API_SELECT_CB_VAR_REF(select_cb)) {
|
struct lwip_sock *sock;
|
||||||
LWIP_ASSERT("select_cb.prev == NULL", API_SELECT_CB_VAR_REF(select_cb).prev == NULL);
|
SYS_ARCH_PROTECT(lev);
|
||||||
select_cb_list = API_SELECT_CB_VAR_REF(select_cb).next;
|
sock = tryget_socket_unconn(i);
|
||||||
} else {
|
if (sock != NULL) {
|
||||||
LWIP_ASSERT("select_cb.prev != NULL", API_SELECT_CB_VAR_REF(select_cb).prev != NULL);
|
/* for now, handle select_waiting==0... */
|
||||||
API_SELECT_CB_VAR_REF(select_cb).prev->next = API_SELECT_CB_VAR_REF(select_cb).next;
|
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
|
||||||
}
|
if (sock->select_waiting > 0) {
|
||||||
|
sock->select_waiting--;
|
||||||
|
}
|
||||||
|
done_socket(sock);
|
||||||
|
} else {
|
||||||
|
/* Not a valid socket */
|
||||||
|
nready = -1;
|
||||||
|
set_errno(EBADF);
|
||||||
|
}
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Take us off the list */
|
||||||
|
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
||||||
|
if (API_SELECT_CB_VAR_REF(select_cb).next != NULL) {
|
||||||
|
API_SELECT_CB_VAR_REF(select_cb).next->prev = API_SELECT_CB_VAR_REF(select_cb).prev;
|
||||||
|
}
|
||||||
|
if (select_cb_list == &API_SELECT_CB_VAR_REF(select_cb)) {
|
||||||
|
LWIP_ASSERT("select_cb.prev == NULL", API_SELECT_CB_VAR_REF(select_cb).prev == NULL);
|
||||||
|
select_cb_list = API_SELECT_CB_VAR_REF(select_cb).next;
|
||||||
|
} else {
|
||||||
|
LWIP_ASSERT("select_cb.prev != NULL", API_SELECT_CB_VAR_REF(select_cb).prev != NULL);
|
||||||
|
API_SELECT_CB_VAR_REF(select_cb).prev->next = API_SELECT_CB_VAR_REF(select_cb).next;
|
||||||
|
}
|
||||||
#if !LWIP_TCPIP_CORE_LOCKING
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
/* Increasing this counter tells select_check_waiters that the list has changed. */
|
/* Increasing this counter tells select_check_waiters that the list has changed. */
|
||||||
select_cb_ctr++;
|
select_cb_ctr++;
|
||||||
#endif
|
#endif
|
||||||
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
||||||
|
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
|
if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
|
||||||
/* don't leave the thread-local semaphore signalled */
|
/* don't leave the thread-local semaphore signalled */
|
||||||
sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1);
|
sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1);
|
||||||
}
|
}
|
||||||
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||||
sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem);
|
sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem);
|
||||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||||
|
|
||||||
if (nready < 0) {
|
|
||||||
/* This happens when a socket got closed while waiting */
|
|
||||||
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
|
||||||
API_SELECT_CB_VAR_FREE(select_cb);
|
API_SELECT_CB_VAR_FREE(select_cb);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waitres == SYS_ARCH_TIMEOUT) {
|
if (nready < 0) {
|
||||||
/* Timeout */
|
/* This happens when a socket got closed while waiting */
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
|
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
||||||
/* This is OK as the local fdsets are empty and nready is zero,
|
API_SELECT_CB_VAR_FREE(select_cb);
|
||||||
or we would have returned earlier. */
|
return -1;
|
||||||
goto return_copy_fdsets;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* See what's set */
|
if (waitres == SYS_ARCH_TIMEOUT) {
|
||||||
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
/* Timeout */
|
||||||
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
|
||||||
|
/* This is OK as the local fdsets are empty and nready is zero,
|
||||||
|
or we would have returned earlier. */
|
||||||
|
} else {
|
||||||
|
/* See what's set now after waiting */
|
||||||
|
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
||||||
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
|
|
||||||
return_copy_fdsets:
|
|
||||||
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
||||||
set_errno(0);
|
set_errno(0);
|
||||||
if (readset) {
|
if (readset) {
|
||||||
@ -2073,7 +2071,6 @@ return_copy_fdsets:
|
|||||||
if (exceptset) {
|
if (exceptset) {
|
||||||
*exceptset = lexceptset;
|
*exceptset = lexceptset;
|
||||||
}
|
}
|
||||||
API_SELECT_CB_VAR_FREE(select_cb);
|
|
||||||
return nready;
|
return nready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user