diff --git a/examples/coap-server.c b/examples/coap-server.c index 7ae162be..d3500593 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -1453,7 +1453,7 @@ main(int argc, char **argv) { } if (result > 0) { if (FD_ISSET(coap_fd, &readfds)) { - result = coap_io_process(ctx, COAP_RUN_NONBLOCK); + result = coap_io_process(ctx, COAP_IO_NO_WAIT); } } } diff --git a/examples/contiki/server.c b/examples/contiki/server.c index efdfe6db..4887212d 100644 --- a/examples/contiki/server.c +++ b/examples/contiki/server.c @@ -216,7 +216,7 @@ PROCESS_THREAD(coap_server_process, ev, data) PROCESS_YIELD(); if(ev == tcpip_event) { /* There is something to read on the endpoint */ - coap_io_process(coap_context, COAP_RUN_BLOCK); + coap_io_process(coap_context, COAP_IO_WAIT); } else if (ev == PROCESS_EVENT_TIMER && etimer_expired(&dirty_timer)) { coap_resource_notify_observers(time_resource, NULL); etimer_reset(&dirty_timer); diff --git a/include/coap2/net.h b/include/coap2/net.h index a848b3ad..be28fa34 100644 --- a/include/coap2/net.h +++ b/include/coap2/net.h @@ -730,8 +730,8 @@ coap_join_mcast_group(coap_context_t *ctx, const char *groupname); * @{ */ -#define COAP_RUN_BLOCK 0 -#define COAP_RUN_NONBLOCK 1 +#define COAP_IO_WAIT 0 +#define COAP_IO_NO_WAIT ((uint32_t)-1) /** * The main I/O processing function. All pending network I/O is completed, @@ -749,16 +749,19 @@ coap_join_mcast_group(coap_context_t *ctx, const char *groupname); * * @param ctx The CoAP context * @param timeout_ms Minimum number of milliseconds to wait for new packets - * before returning. If COAP_RUN_BLOCK, the call will block - * until at least one new packet is received. If - * COAP_RUN_NONBLOCK, the function will return immediately - * following without waiting for any new input not already - * available. + * before returning after doing any processing. + * If COAP_IO_WAIT, the call will block until the next + * internal action (e.g. packet retransmit) if any, or block + * until the next packet is received whichever is the sooner + * and do the necessary processing. + * If COAP_IO_NO_WAIT, the function will return immediately + * after processing without waiting for any new input + * packets to arrive. * * @return Number of milliseconds spent in function or @c -1 if there was * an error */ -int coap_io_process(coap_context_t *ctx, unsigned int timeout_ms); +int coap_io_process(coap_context_t *ctx, uint32_t timeout_ms); /** * @deprecated Use coap_io_process() instead. @@ -767,17 +770,20 @@ int coap_io_process(coap_context_t *ctx, unsigned int timeout_ms); * * @param ctx The CoAP context * @param timeout_ms Minimum number of milliseconds to wait for new packets - * before returning. If COAP_RUN_BLOCK, the call will block - * until at least one new packet is received. If - * COAP_RUN_NONBLOCK, the function will return immediately - * following without waiting for any new input not already - * available. + * before returning after doing any processing. + * If COAP_IO_WAIT, the call will block until the next + * internal action (e.g. packet retransmit) if any, or block + * until the next packet is received whichever is the sooner + * and do the necessary processing. + * If COAP_IO_NO_WAIT, the function will return immediately + * after processing without waiting for any new input + * packets to arrive. * * @return Number of milliseconds spent in function or @c -1 if there was * an error */ COAP_STATIC_INLINE COAP_DEPRECATED int -coap_run_once(coap_context_t *ctx, unsigned int timeout_ms) +coap_run_once(coap_context_t *ctx, uint32_t timeout_ms) { return coap_io_process(ctx, timeout_ms); } @@ -787,10 +793,14 @@ coap_run_once(coap_context_t *ctx, unsigned int timeout_ms) * * @param ctx The CoAP context * @param timeout_ms Minimum number of milliseconds to wait for new packets - * before returning. If COAP_RUN_BLOCK, the call will block - * until at least one new packet is received. If - * COAP_RUN_NONBLOCK, the function will return immediately - * after processing any existing input packets. + * before returning after doing any processing. + * If COAP_IO_WAIT, the call will block until the next + * internal action (e.g. packet retransmit) if any, or block + * until the next packet is received whichever is the sooner + * and do the necessary processing. + * If COAP_IO_NO_WAIT, the function will return immediately + * after processing without waiting for any new input + * packets to arrive. * @param nfds The maximum FD set in readfds, writefds or exceptfds * plus one, * @param readfds Read FDs to additionally check for in internal select() @@ -805,7 +815,7 @@ coap_run_once(coap_context_t *ctx, unsigned int timeout_ms) * if there was an error. If defined, readfds, writefds, exceptfds * are updated as returned by the internal select() call. */ -int coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, +int coap_io_process_with_fds(coap_context_t *ctx, uint32_t timeout_ms, int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds); diff --git a/man/coap_io.txt.in b/man/coap_io.txt.in index 71268802..c9daeed3 100644 --- a/man/coap_io.txt.in +++ b/man/coap_io.txt.in @@ -18,16 +18,16 @@ SYNOPSIS -------- *#include * -*int coap_io_process(coap_context_t *_context_, unsigned int _timeout_ms_)*; +*int coap_io_process(coap_context_t *_context_, uint32_t _timeout_ms_)*; *int coap_io_process_with_fds(coap_context_t *_context_, -unsigned int _timeout_ms_, int _nfds_, fd_set *_readfds_, fd_set *_writefds_, +uint32_t _timeout_ms_, int _nfds_, fd_set *_readfds_, fd_set *_writefds_, fd_set *_exceptfds_)*; *int coap_context_get_coap_fd(coap_context_t *_context_)*; *unsigned int coap_io_prepare_io(coap_context_t *_context_, -coap_socket_t *_sockets[]_, unsigned int _max_sockets_, +coap_socket_t *_sockets_[], unsigned int _max_sockets_, unsigned int *_num_sockets_, coap_tick_t _now_)*; *void coap_io_do_io(coap_context_t *_context_, coap_tick_t _now_)*; @@ -35,12 +35,12 @@ unsigned int *_num_sockets_, coap_tick_t _now_)*; *unsigned int coap_io_prepare_epoll(coap_context_t *_context_, coap_tick_t _now_)*; -*int coap_io_do_epoll(coap_context_t *_context_, struct epoll_event *_events_, -size_t _nevents_)* +*void coap_io_do_epoll(coap_context_t *_context_, struct epoll_event *_events_, +size_t _nevents_)*; Link with *-lcoap-@LIBCOAP_API_VERSION@*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, -*-lcoap-@LIBCOAP_API_VERSION@-openssl* or -*-lcoap-@LIBCOAP_API_VERSION@-tinydtls* depending on your (D)TLS library +*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* +or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls* depending on your (D)TLS library type. DESCRIPTION @@ -56,13 +56,15 @@ up to _timeout_ms_ milli-seconds before returning. There are 2 special case _timeout_ms_ values. [source, c] ---- -#define COAP_RUN_BLOCK 0 -#define COAP_RUN_NONBLOCK 1 +#define COAP_IO_WAIT 0 +#define COAP_IO_NO_WAIT ((uint32_t)-1) ---- -If _timeout_ms_ is set to COAP_RUN_BLOCK, then *coap_io_process*() will wait -indefinitely for the first new input packet to come in, or for when to -re-transmit a packet. If _timeout_ms_ is set to COAP_RUN_NONBLOCK, then there -is no wait if there is no more input or output to process. +If _timeout_ms_ is set to COAP_IO_WAIT, then *coap_io_process*() will block +until the next internal action (e.g. packet retransmit) if any, or block until +the next packet is received whichever is the sooner and do the necessary +processing. If _timeout_ms_ is set to COAP_IO_NO_WAIT, then *coap_io_process*() +will return immediately after processing without waiting for any new input +packets to arrive. There are two methods of how to call *coap_io_process*(). @@ -73,7 +75,7 @@ _timeout_ms_, but more frequently if there is input / retransmission traffic. 2. Wait on the file descriptor returned by *coap_context_get_coap_fd*() using *select*() or an event returned by epoll_wait(). If 'read' is available on the file descriptor, call *coap_io_process*() with _timeout_ms_ set to -COAP_RUN_NONBLOCK. + +COAP_IO_NO_WAIT. + *NOTE*: This second method is only available for environments that support epoll (mostly Linux) with libcoap compiled to use *epoll* (the default) as libcoap will then be using *epoll* internally to process all the file descriptors of @@ -176,7 +178,7 @@ int main(int argc, char *argv[]){ coap_context_t *ctx = NULL; unsigned wait_ms; - + /* Remove (void) definition if variable is used */ (void)argc; (void)argv; @@ -219,7 +221,7 @@ int main(int argc, char *argv[]){ unsigned wait_ms; fd_set readfds; int nfds = 0; - + /* Remove (void) definition if variable is used */ (void)argc; (void)argv; @@ -269,7 +271,7 @@ int main(int argc, char *argv[]){ int coap_fd; fd_set m_readfds; int nfds; - + /* Remove (void) definition if variable is used */ (void)argc; (void)argv; @@ -280,6 +282,7 @@ int main(int argc, char *argv[]){ } coap_fd = coap_context_get_coap_fd(ctx); if (coap_fd == -1) { + /* epoll is not supported */ exit(1); } FD_ZERO(&m_readfds); @@ -301,7 +304,7 @@ int main(int argc, char *argv[]){ } if (result > 0) { if (FD_ISSET(coap_fd, &readfds)) { - result = coap_io_process(ctx, COAP_RUN_NONBLOCK); + result = coap_io_process(ctx, COAP_IO_NO_WAIT); if (result < 0) { /* There is an internal issue */ break; @@ -340,7 +343,7 @@ int main(int argc, char *argv[]){ struct epoll_event events[MAX_EVENTS]; int nevents; int i; - + /* Remove (void) definition if variable is used */ (void)argc; (void)argv; @@ -377,7 +380,7 @@ int main(int argc, char *argv[]){ } for (i = 0; i < nevents; i++) { if (events[i].data.fd == coap_fd) { - result = coap_io_process(ctx, COAP_RUN_NONBLOCK); + result = coap_io_process(ctx, COAP_IO_NO_WAIT); if (result < 0) { /* There is an internal issue */ break; diff --git a/src/coap_io.c b/src/coap_io.c index c1ca5dd6..0738e857 100644 --- a/src/coap_io.c +++ b/src/coap_io.c @@ -43,6 +43,9 @@ #ifdef COAP_EPOLL_SUPPORT #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #endif /* COAP_EPOLL_SUPPORT */ #ifdef WITH_CONTIKI @@ -991,6 +994,10 @@ coap_io_prepare_epoll(coap_context_t *ctx, coap_tick_t now) { #endif /* COAP_EPOLL_SUPPORT */ } +/* + * return 0 No i/o pending + * +ve millisecs to next i/o activity + */ unsigned int coap_io_prepare_io(coap_context_t *ctx, coap_socket_t *sockets[], @@ -1174,12 +1181,12 @@ coap_io_prepare_io(coap_context_t *ctx, } int -coap_io_process(coap_context_t *ctx, unsigned timeout_ms) { +coap_io_process(coap_context_t *ctx, uint32_t timeout_ms) { return coap_io_process_with_fds(ctx, timeout_ms, 0, NULL, NULL, NULL); } int -coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, +coap_io_process_with_fds(coap_context_t *ctx, uint32_t timeout_ms, int enfds, fd_set *ereadfds, fd_set *ewritefds, fd_set *eexceptfds) { #if COAP_CONSTRAINED_STACK @@ -1256,9 +1263,12 @@ coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, #endif /* !COAP_DISABLE_TCP */ } - if ( timeout > 0 ) { - if (timeout == COAP_RUN_NONBLOCK) - timeout = 0; + if (timeout_ms == COAP_IO_NO_WAIT) { + tv.tv_usec = 0; + tv.tv_sec = 0; + timeout = 1; + } + else if (timeout > 0) { tv.tv_usec = (timeout % 1000) * 1000; tv.tv_sec = (long)(timeout / 1000); } @@ -1322,10 +1332,17 @@ coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, int etimeout = timeout; /* Potentially adjust based on what the caller wants */ - if (timeout_ms == COAP_RUN_BLOCK) - etimeout = -1; - else if (timeout_ms == COAP_RUN_NONBLOCK) + if (timeout_ms == COAP_IO_NO_WAIT) { etimeout = 0; + } + else if (timeout == COAP_IO_WAIT) { + /* coap_io_prepare_epoll() returned 0 and timeout_ms COAP_IO_WAIT (0) */ + etimeout = -1; + } + else if (etimeout < 0) { + /* epoll_wait cannot wait longer than this as int timeout parameter */ + etimeout = INT_MAX; + } nfds = epoll_wait(ctx->epfd, events, COAP_MAX_EPOLL_EVENTS, etimeout); if (nfds < 0) { @@ -1339,11 +1356,11 @@ coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, coap_io_do_epoll(ctx, events, nfds); /* - * reset to COAP_RUN_NONBLOCK (which causes etimeout to become 0) + * reset to COAP_IO_NO_WAIT (which causes etimeout to become 0) * incase we have to do another iteration * (COAP_MAX_EPOLL_EVENTS insufficient) */ - timeout_ms = COAP_RUN_NONBLOCK; + timeout_ms = COAP_IO_NO_WAIT; /* Keep retrying until less than COAP_MAX_EPOLL_EVENTS are returned */ } while (nfds == COAP_MAX_EPOLL_EVENTS); @@ -1359,7 +1376,7 @@ coap_io_process_with_fds(coap_context_t *ctx, unsigned int timeout_ms, } #else /* WITH_CONTIKI */ -int coap_io_process(coap_context_t *ctx, unsigned int timeout_ms) { +int coap_io_process(coap_context_t *ctx, uint32_t timeout_ms) { coap_tick_t now; coap_ticks(&now);