diff --git a/docs/c-api/mg_net.h/mg_mgr_free.md b/docs/c-api/mg_net.h/mg_mgr_free.md index d2df34e4c268278da83abc9d4c2b725aea297943..60ad75bdc512b4dbf8ca0e1debf5b92cad1e97d0 100644 --- a/docs/c-api/mg_net.h/mg_mgr_free.md +++ b/docs/c-api/mg_net.h/mg_mgr_free.md @@ -3,7 +3,7 @@ title: "mg_mgr_free()" decl_name: "mg_mgr_free" symbol_kind: "func" signature: | - void mg_mgr_free(struct mg_mgr *); + void mg_mgr_free(struct mg_mgr *mgr); --- De-initialises Mongoose manager. diff --git a/docs/c-api/mg_net.h/mg_mgr_poll.md b/docs/c-api/mg_net.h/mg_mgr_poll.md index b70c31b6db0229534694d1a8e31a8328a2e2f723..ef48a190826f11664f3d703b95ba72368ad16a8b 100644 --- a/docs/c-api/mg_net.h/mg_mgr_poll.md +++ b/docs/c-api/mg_net.h/mg_mgr_poll.md @@ -3,11 +3,11 @@ title: "mg_mgr_poll()" decl_name: "mg_mgr_poll" symbol_kind: "func" signature: | - time_t mg_mgr_poll(struct mg_mgr *, int milli); + int mg_mgr_poll(struct mg_mgr *mgr, int milli); --- This function performs the actual IO and must be called in a loop -(an event loop). It returns the current timestamp. +(an event loop). It returns number of user events generated (except POLLs). `milli` is the maximum number of milliseconds to sleep. `mg_mgr_poll()` checks all connections for IO readiness. If at least one of the connections is IO-ready, `mg_mgr_poll()` triggers the respective diff --git a/docs/c-api/mg_net.h/struct_mg_mgr.md b/docs/c-api/mg_net.h/struct_mg_mgr.md index d33727c38d2314ec252096ed8a560d0a59b02f4e..44efa5fdf21f07fb692da61ecd29132fcc7777a0 100644 --- a/docs/c-api/mg_net.h/struct_mg_mgr.md +++ b/docs/c-api/mg_net.h/struct_mg_mgr.md @@ -13,6 +13,7 @@ signature: | #endif void *user_data; /* User data */ int num_ifaces; + int num_calls; struct mg_iface **ifaces; /* network interfaces */ const char *nameserver; /* DNS server to use */ }; diff --git a/mongoose.c b/mongoose.c index d09345c5ea54514447bc222648d601caad1450a7..7b0170c2b5563b804b2bdf3e16d2b4355a43f960 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2408,6 +2408,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc, (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK); } } + if (ev != MG_EV_POLL) nc->mgr->num_calls++; if (ev != MG_EV_POLL) { DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc, ev_handler == nc->handler ? "user" : "proto", nc->flags, @@ -2585,19 +2586,14 @@ void mg_mgr_free(struct mg_mgr *m) { MG_FREE((char *) m->nameserver); } -time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) { - int i; - time_t now = 0; /* oh GCC, seriously ? */ - - if (m->num_ifaces == 0) { - LOG(LL_ERROR, ("cannot poll: no interfaces")); - return 0; - } +int mg_mgr_poll(struct mg_mgr *m, int timeout_ms) { + int i, num_calls_before = m->num_calls; for (i = 0; i < m->num_ifaces; i++) { - now = m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms); + m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms); } - return now; + + return (m->num_calls - num_calls_before); } int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap) { @@ -3585,6 +3581,18 @@ struct mg_iface *mg_find_iface(struct mg_mgr *mgr, } return NULL; } + +double mg_mgr_min_timer(const struct mg_mgr *mgr) { + double min_timer = 0; + struct mg_connection *nc; + for (nc = mgr->active_connections; nc != NULL; nc = nc->next) { + if (nc->ev_timer_time <= 0) continue; + if (min_timer == 0 || nc->ev_timer_time < min_timer) { + min_timer = nc->ev_timer_time; + } + } + return min_timer; +} #ifdef MG_MODULE_LINES #line 1 "mongoose/src/mg_net_if_socket.c" #endif @@ -15716,38 +15724,6 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) { return now; } -uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) { - struct mg_connection *nc; - double now; - double min_timer = 0; - int num_timers = 0; - mg_ev_mgr_lwip_process_signals(mgr); - for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { - struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; - if (nc->ev_timer_time > 0) { - if (num_timers == 0 || nc->ev_timer_time < min_timer) { - min_timer = nc->ev_timer_time; - } - num_timers++; - } - /* We want and can send data, request a poll immediately. */ - if (nc->sock != INVALID_SOCKET && mg_lwip_if_can_send(nc, cs)) { - return 0; - } - } - uint32_t timeout_ms = ~0; - now = mg_time(); - if (num_timers > 0) { - /* If we have a timer that is past due, do a poll ASAP. */ - if (min_timer < now) return 0; - double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */; - if (timer_timeout_ms < timeout_ms) { - timeout_ms = timer_timeout_ms; - } - } - return timeout_ms; -} - #endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */ #ifdef MG_MODULE_LINES #line 1 "common/platforms/wince/wince_libc.c" diff --git a/mongoose.h b/mongoose.h index 2667c75905388b73424764bea8f5a93e63f1fecf..7c179d692fa74ed1faca880f3fed47396312b20e 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2030,7 +2030,6 @@ typedef int sock_t; #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL struct mg_mgr; struct mg_connection; -uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr); void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, int interval, int count); #endif @@ -3718,6 +3717,12 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, /* Deliver a POLL event to the connection. */ int mg_if_poll(struct mg_connection *nc, double now); +/* + * Return minimal timer value amoung connections in the manager. + * Returns 0 if there aren't any timers. + */ +double mg_mgr_min_timer(const struct mg_mgr *mgr); + #ifdef __cplusplus } #endif /* __cplusplus */ @@ -3875,6 +3880,7 @@ struct mg_mgr { #endif void *user_data; /* User data */ int num_ifaces; + int num_calls; struct mg_iface **ifaces; /* network interfaces */ const char *nameserver; /* DNS server to use */ }; @@ -3987,17 +3993,17 @@ void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, * * Closes and deallocates all active connections. */ -void mg_mgr_free(struct mg_mgr *); +void mg_mgr_free(struct mg_mgr *mgr); /* * This function performs the actual IO and must be called in a loop - * (an event loop). It returns the current timestamp. + * (an event loop). It returns number of user events generated (except POLLs). * `milli` is the maximum number of milliseconds to sleep. * `mg_mgr_poll()` checks all connections for IO readiness. If at least one * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective * event handlers and returns. */ -time_t mg_mgr_poll(struct mg_mgr *, int milli); +int mg_mgr_poll(struct mg_mgr *mgr, int milli); #if MG_ENABLE_BROADCAST /* diff --git a/src/common/platforms/lwip/mg_lwip.h b/src/common/platforms/lwip/mg_lwip.h index c0d4081e88ee686c93c6c4f7d4ac65e2ab0cf349..c15e2ee2db3a1d31eb07a54667c5ba4dc6380f50 100644 --- a/src/common/platforms/lwip/mg_lwip.h +++ b/src/common/platforms/lwip/mg_lwip.h @@ -66,7 +66,6 @@ typedef int sock_t; #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL struct mg_mgr; struct mg_connection; -uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr); void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, int interval, int count); #endif diff --git a/src/common/platforms/lwip/mg_lwip_ev_mgr.c b/src/common/platforms/lwip/mg_lwip_ev_mgr.c index 39937fc919b01673747b9a68da2666f9c617f1e0..b495464e91434ee337cbb533fe8a3d4d5cd0b7cd 100644 --- a/src/common/platforms/lwip/mg_lwip_ev_mgr.c +++ b/src/common/platforms/lwip/mg_lwip_ev_mgr.c @@ -167,36 +167,4 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) { return now; } -uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) { - struct mg_connection *nc; - double now; - double min_timer = 0; - int num_timers = 0; - mg_ev_mgr_lwip_process_signals(mgr); - for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { - struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; - if (nc->ev_timer_time > 0) { - if (num_timers == 0 || nc->ev_timer_time < min_timer) { - min_timer = nc->ev_timer_time; - } - num_timers++; - } - /* We want and can send data, request a poll immediately. */ - if (nc->sock != INVALID_SOCKET && mg_lwip_if_can_send(nc, cs)) { - return 0; - } - } - uint32_t timeout_ms = ~0; - now = mg_time(); - if (num_timers > 0) { - /* If we have a timer that is past due, do a poll ASAP. */ - if (min_timer < now) return 0; - double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */; - if (timer_timeout_ms < timeout_ms) { - timeout_ms = timer_timeout_ms; - } - } - return timeout_ms; -} - #endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */ diff --git a/src/mg_net.c b/src/mg_net.c index 5c961409148cd6f57015bf56afc611550b8e2a7a..3862fa892fbfb06b74123b70ced48aec9a0b1f06 100644 --- a/src/mg_net.c +++ b/src/mg_net.c @@ -99,6 +99,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc, (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK); } } + if (ev != MG_EV_POLL) nc->mgr->num_calls++; if (ev != MG_EV_POLL) { DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc, ev_handler == nc->handler ? "user" : "proto", nc->flags, @@ -276,19 +277,14 @@ void mg_mgr_free(struct mg_mgr *m) { MG_FREE((char *) m->nameserver); } -time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) { - int i; - time_t now = 0; /* oh GCC, seriously ? */ - - if (m->num_ifaces == 0) { - LOG(LL_ERROR, ("cannot poll: no interfaces")); - return 0; - } +int mg_mgr_poll(struct mg_mgr *m, int timeout_ms) { + int i, num_calls_before = m->num_calls; for (i = 0; i < m->num_ifaces; i++) { - now = m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms); + m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms); } - return now; + + return (m->num_calls - num_calls_before); } int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap) { diff --git a/src/mg_net.h b/src/mg_net.h index 90b42b47af6dc936c4fb4e282c609e8a858edc4b..d854e770a2db828d1a378904109ee8d05e40f031 100644 --- a/src/mg_net.h +++ b/src/mg_net.h @@ -89,6 +89,7 @@ struct mg_mgr { #endif void *user_data; /* User data */ int num_ifaces; + int num_calls; struct mg_iface **ifaces; /* network interfaces */ const char *nameserver; /* DNS server to use */ }; @@ -201,17 +202,17 @@ void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, * * Closes and deallocates all active connections. */ -void mg_mgr_free(struct mg_mgr *); +void mg_mgr_free(struct mg_mgr *mgr); /* * This function performs the actual IO and must be called in a loop - * (an event loop). It returns the current timestamp. + * (an event loop). It returns number of user events generated (except POLLs). * `milli` is the maximum number of milliseconds to sleep. * `mg_mgr_poll()` checks all connections for IO readiness. If at least one * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective * event handlers and returns. */ -time_t mg_mgr_poll(struct mg_mgr *, int milli); +int mg_mgr_poll(struct mg_mgr *mgr, int milli); #if MG_ENABLE_BROADCAST /* diff --git a/src/mg_net_if.c b/src/mg_net_if.c index 2a93dcfd4a8440d235b8cf39d911bc213cf0e4a5..c91feb9960d5040570144b75e8986a06fba77956 100644 --- a/src/mg_net_if.c +++ b/src/mg_net_if.c @@ -39,3 +39,15 @@ struct mg_iface *mg_find_iface(struct mg_mgr *mgr, } return NULL; } + +double mg_mgr_min_timer(const struct mg_mgr *mgr) { + double min_timer = 0; + struct mg_connection *nc; + for (nc = mgr->active_connections; nc != NULL; nc = nc->next) { + if (nc->ev_timer_time <= 0) continue; + if (min_timer == 0 || nc->ev_timer_time < min_timer) { + min_timer = nc->ev_timer_time; + } + } + return min_timer; +} diff --git a/src/mg_net_if.h b/src/mg_net_if.h index cba58fb95fd2d4688c8e9059b913516ac7927c9e..1239d54a0ae6af2cb4092fe0b8902900c871b7e8 100644 --- a/src/mg_net_if.h +++ b/src/mg_net_if.h @@ -118,6 +118,12 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, /* Deliver a POLL event to the connection. */ int mg_if_poll(struct mg_connection *nc, double now); +/* + * Return minimal timer value amoung connections in the manager. + * Returns 0 if there aren't any timers. + */ +double mg_mgr_min_timer(const struct mg_mgr *mgr); + #ifdef __cplusplus } #endif /* __cplusplus */