mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-07 01:07:19 +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"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_mgr_free(struct mg_mgr *);
|
||||
void mg_mgr_free(struct mg_mgr *mgr);
|
||||
---
|
||||
|
||||
De-initialises Mongoose manager.
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
};
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
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"
|
||||
|
14
mongoose.h
14
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
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user