| 2338 | #endif /* LWIP_NETCONN_FULLDUPLEX */ |
| 2339 | |
| 2340 | int |
| 2341 | lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) |
| 2342 | { |
| 2343 | u32_t waitres = 0; |
| 2344 | int nready; |
| 2345 | u32_t msectimeout; |
| 2346 | #if LWIP_NETCONN_SEM_PER_THREAD |
| 2347 | int waited = 0; |
| 2348 | #endif |
| 2349 | |
| 2350 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n", |
| 2351 | (void*)fds, (int)nfds, timeout)); |
| 2352 | LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)), |
| 2353 | set_errno(EINVAL); return -1;); |
| 2354 | |
| 2355 | lwip_poll_inc_sockets_used(fds, nfds); |
| 2356 | |
| 2357 | /* Go through each struct pollfd to count number of structures |
| 2358 | which currently match */ |
| 2359 | nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR); |
| 2360 | |
| 2361 | if (nready < 0) { |
| 2362 | lwip_poll_dec_sockets_used(fds, nfds); |
| 2363 | return -1; |
| 2364 | } |
| 2365 | |
| 2366 | /* If we don't have any current events, then suspend if we are supposed to */ |
| 2367 | if (!nready) { |
| 2368 | API_SELECT_CB_VAR_DECLARE(select_cb); |
| 2369 | |
| 2370 | if (timeout == 0) { |
| 2371 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); |
| 2372 | goto return_success; |
| 2373 | } |
| 2374 | API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); |
| 2375 | memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); |
| 2376 | |
| 2377 | /* None ready: add our semaphore to list: |
| 2378 | We don't actually need any dynamic memory. Our entry on the |
| 2379 | list is only valid while we are in this function, so it's ok |
| 2380 | to use local variables. */ |
| 2381 | |
| 2382 | API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; |
| 2383 | API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; |
| 2384 | #if LWIP_NETCONN_SEM_PER_THREAD |
| 2385 | API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); |
| 2386 | #else /* LWIP_NETCONN_SEM_PER_THREAD */ |
| 2387 | if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { |
| 2388 | /* failed to create semaphore */ |
| 2389 | set_errno(EAGAIN); |
| 2390 | lwip_poll_dec_sockets_used(fds, nfds); |
| 2391 | API_SELECT_CB_VAR_FREE(select_cb); |
| 2392 | return -1; |
| 2393 | } |
| 2394 | #endif /* LWIP_NETCONN_SEM_PER_THREAD */ |
| 2395 | |
| 2396 | lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); |
| 2397 | |