mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-07 09:27:05 +08:00
Refactor mg polling
* Change return type of mg_mgr_poll to return number of events * Add mg_mgr_min_timer * Refactor main poll loop to remove LwIP-specific stuff CL: Refactor mg polling PUBLISHED_FROM=dc94618b32fa3c84a2f053bd04d134297780ec82
This commit is contained in:
parent
955d4a3129
commit
421e099f2b
@ -3,7 +3,7 @@ title: "mg_mgr_free()"
|
|||||||
decl_name: "mg_mgr_free"
|
decl_name: "mg_mgr_free"
|
||||||
symbol_kind: "func"
|
symbol_kind: "func"
|
||||||
signature: |
|
signature: |
|
||||||
void mg_mgr_free(struct mg_mgr *);
|
void mg_mgr_free(struct mg_mgr *mgr);
|
||||||
---
|
---
|
||||||
|
|
||||||
De-initialises Mongoose manager.
|
De-initialises Mongoose manager.
|
||||||
|
@ -3,11 +3,11 @@ title: "mg_mgr_poll()"
|
|||||||
decl_name: "mg_mgr_poll"
|
decl_name: "mg_mgr_poll"
|
||||||
symbol_kind: "func"
|
symbol_kind: "func"
|
||||||
signature: |
|
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
|
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.
|
`milli` is the maximum number of milliseconds to sleep.
|
||||||
`mg_mgr_poll()` checks all connections for IO readiness. If at least one
|
`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
|
of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
|
||||||
|
@ -13,6 +13,7 @@ signature: |
|
|||||||
#endif
|
#endif
|
||||||
void *user_data; /* User data */
|
void *user_data; /* User data */
|
||||||
int num_ifaces;
|
int num_ifaces;
|
||||||
|
int num_calls;
|
||||||
struct mg_iface **ifaces; /* network interfaces */
|
struct mg_iface **ifaces; /* network interfaces */
|
||||||
const char *nameserver; /* DNS server to use */
|
const char *nameserver; /* DNS server to use */
|
||||||
};
|
};
|
||||||
|
60
mongoose.c
60
mongoose.c
@ -2408,6 +2408,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
|
|||||||
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ev != MG_EV_POLL) nc->mgr->num_calls++;
|
||||||
if (ev != MG_EV_POLL) {
|
if (ev != MG_EV_POLL) {
|
||||||
DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc,
|
DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc,
|
||||||
ev_handler == nc->handler ? "user" : "proto", nc->flags,
|
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);
|
MG_FREE((char *) m->nameserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
|
int mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
|
||||||
int i;
|
int i, num_calls_before = m->num_calls;
|
||||||
time_t now = 0; /* oh GCC, seriously ? */
|
|
||||||
|
|
||||||
if (m->num_ifaces == 0) {
|
|
||||||
LOG(LL_ERROR, ("cannot poll: no interfaces"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < m->num_ifaces; i++) {
|
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) {
|
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;
|
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
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/mg_net_if_socket.c"
|
#line 1 "mongoose/src/mg_net_if_socket.c"
|
||||||
#endif
|
#endif
|
||||||
@ -15716,38 +15724,6 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
|
|||||||
return now;
|
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 */
|
#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
|
||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/wince/wince_libc.c"
|
#line 1 "common/platforms/wince/wince_libc.c"
|
||||||
|
14
mongoose.h
14
mongoose.h
@ -2030,7 +2030,6 @@ typedef int sock_t;
|
|||||||
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
||||||
struct mg_mgr;
|
struct mg_mgr;
|
||||||
struct mg_connection;
|
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,
|
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
||||||
int interval, int count);
|
int interval, int count);
|
||||||
#endif
|
#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. */
|
/* Deliver a POLL event to the connection. */
|
||||||
int mg_if_poll(struct mg_connection *nc, double now);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
@ -3875,6 +3880,7 @@ struct mg_mgr {
|
|||||||
#endif
|
#endif
|
||||||
void *user_data; /* User data */
|
void *user_data; /* User data */
|
||||||
int num_ifaces;
|
int num_ifaces;
|
||||||
|
int num_calls;
|
||||||
struct mg_iface **ifaces; /* network interfaces */
|
struct mg_iface **ifaces; /* network interfaces */
|
||||||
const char *nameserver; /* DNS server to use */
|
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.
|
* 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
|
* 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.
|
* `milli` is the maximum number of milliseconds to sleep.
|
||||||
* `mg_mgr_poll()` checks all connections for IO readiness. If at least one
|
* `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
|
* of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
|
||||||
* event handlers and returns.
|
* 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
|
#if MG_ENABLE_BROADCAST
|
||||||
/*
|
/*
|
||||||
|
@ -66,7 +66,6 @@ typedef int sock_t;
|
|||||||
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
||||||
struct mg_mgr;
|
struct mg_mgr;
|
||||||
struct mg_connection;
|
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,
|
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
||||||
int interval, int count);
|
int interval, int count);
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,36 +167,4 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
|
|||||||
return now;
|
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 */
|
#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
|
||||||
|
16
src/mg_net.c
16
src/mg_net.c
@ -99,6 +99,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
|
|||||||
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ev != MG_EV_POLL) nc->mgr->num_calls++;
|
||||||
if (ev != MG_EV_POLL) {
|
if (ev != MG_EV_POLL) {
|
||||||
DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc,
|
DBG(("%p after %s flags=0x%lx rmbl=%d smbl=%d", nc,
|
||||||
ev_handler == nc->handler ? "user" : "proto", nc->flags,
|
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);
|
MG_FREE((char *) m->nameserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
|
int mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
|
||||||
int i;
|
int i, num_calls_before = m->num_calls;
|
||||||
time_t now = 0; /* oh GCC, seriously ? */
|
|
||||||
|
|
||||||
if (m->num_ifaces == 0) {
|
|
||||||
LOG(LL_ERROR, ("cannot poll: no interfaces"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < m->num_ifaces; i++) {
|
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) {
|
int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap) {
|
||||||
|
@ -89,6 +89,7 @@ struct mg_mgr {
|
|||||||
#endif
|
#endif
|
||||||
void *user_data; /* User data */
|
void *user_data; /* User data */
|
||||||
int num_ifaces;
|
int num_ifaces;
|
||||||
|
int num_calls;
|
||||||
struct mg_iface **ifaces; /* network interfaces */
|
struct mg_iface **ifaces; /* network interfaces */
|
||||||
const char *nameserver; /* DNS server to use */
|
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.
|
* 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
|
* 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.
|
* `milli` is the maximum number of milliseconds to sleep.
|
||||||
* `mg_mgr_poll()` checks all connections for IO readiness. If at least one
|
* `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
|
* of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
|
||||||
* event handlers and returns.
|
* 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
|
#if MG_ENABLE_BROADCAST
|
||||||
/*
|
/*
|
||||||
|
@ -39,3 +39,15 @@ struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
|
|||||||
}
|
}
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
@ -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. */
|
/* Deliver a POLL event to the connection. */
|
||||||
int mg_if_poll(struct mg_connection *nc, double now);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
Loading…
Reference in New Issue
Block a user