mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-23 11:44:53 +00:00
Fix #1520 - move state to struct mg_mgr
This commit is contained in:
1 parent
66376885e9
commit
ef44f90491
24 files changed
+218
-276
No files matched your search
@@ -12,21 +12,20 @@ struct dns_data {
|
||||
uint16_t txnid;
|
||||
};
|
||||
|
||||
static struct dns_data *s_reqs; // Active DNS requests
|
||||
|
||||
static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int,
|
||||
struct mg_dns *, bool);
|
||||
|
||||
static void mg_dns_free(struct dns_data *d) {
|
||||
LIST_DELETE(struct dns_data, &s_reqs, d);
|
||||
static void mg_dns_free(struct mg_connection *c, struct dns_data *d) {
|
||||
LIST_DELETE(struct dns_data,
|
||||
(struct dns_data **) &c->mgr->active_dns_requests, d);
|
||||
free(d);
|
||||
}
|
||||
|
||||
void mg_resolve_cancel(struct mg_connection *c) {
|
||||
struct dns_data *tmp, *d;
|
||||
for (d = s_reqs; d != NULL; d = tmp) {
|
||||
struct dns_data *tmp, *d = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
for (; d != NULL; d = tmp) {
|
||||
tmp = d->next;
|
||||
if (d->c == c) mg_dns_free(d);
|
||||
if (d->c == c) mg_dns_free(c, d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +138,8 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
struct dns_data *d, *tmp;
|
||||
if (ev == MG_EV_POLL) {
|
||||
uint64_t now = *(uint64_t *) ev_data;
|
||||
for (d = s_reqs; d != NULL; d = tmp) {
|
||||
for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
|
||||
d = tmp) {
|
||||
tmp = d->next;
|
||||
// MG_DEBUG ("%lu %lu dns poll", d->expire, now));
|
||||
if (now > d->expire) mg_error(d->c, "DNS timeout");
|
||||
@@ -153,7 +153,8 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
free(s);
|
||||
} else {
|
||||
MG_VERBOSE(("%s %d", dm.name, dm.resolved));
|
||||
for (d = s_reqs; d != NULL; d = tmp) {
|
||||
for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
|
||||
d = tmp) {
|
||||
tmp = d->next;
|
||||
// MG_INFO(("d %p %hu %hu", d, d->txnid, dm.txnid));
|
||||
if (dm.txnid != d->txnid) continue;
|
||||
@@ -176,17 +177,18 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
} else {
|
||||
MG_ERROR(("%lu already resolved", d->c->id));
|
||||
}
|
||||
mg_dns_free(d);
|
||||
mg_dns_free(c, d);
|
||||
resolved = 1;
|
||||
}
|
||||
}
|
||||
if (!resolved) MG_ERROR(("stray DNS reply"));
|
||||
c->recv.len = 0;
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
for (d = s_reqs; d != NULL; d = tmp) {
|
||||
for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
|
||||
d = tmp) {
|
||||
tmp = d->next;
|
||||
mg_error(d->c, "DNS error");
|
||||
mg_dns_free(d);
|
||||
mg_dns_free(c, d);
|
||||
}
|
||||
}
|
||||
(void) fn_data;
|
||||
@@ -236,10 +238,11 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
||||
} else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
|
||||
mg_error(c, "resolve OOM");
|
||||
} else {
|
||||
struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
char buf[100];
|
||||
d->txnid = s_reqs ? (uint16_t) (s_reqs->txnid + 1) : 1;
|
||||
d->next = s_reqs;
|
||||
s_reqs = d;
|
||||
d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
|
||||
d->next = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
c->mgr->active_dns_requests = d;
|
||||
d->expire = mg_millis() + (uint64_t) ms;
|
||||
d->c = c;
|
||||
c->is_resolving = 1;
|
||||
|
||||
+2
-50
@@ -289,68 +289,20 @@ void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
|
||||
static const char *mg_http_status_code_str(int status_code) {
|
||||
switch (status_code) {
|
||||
case 100: return "Continue";
|
||||
case 101: return "Switching Protocols";
|
||||
case 102: return "Processing";
|
||||
case 200: return "OK";
|
||||
case 201: return "Created";
|
||||
case 202: return "Accepted";
|
||||
case 203: return "Non-authoritative Information";
|
||||
case 204: return "No Content";
|
||||
case 205: return "Reset Content";
|
||||
case 206: return "Partial Content";
|
||||
case 207: return "Multi-Status";
|
||||
case 208: return "Already Reported";
|
||||
case 226: return "IM Used";
|
||||
case 300: return "Multiple Choices";
|
||||
case 301: return "Moved Permanently";
|
||||
case 302: return "Found";
|
||||
case 303: return "See Other";
|
||||
case 304: return "Not Modified";
|
||||
case 305: return "Use Proxy";
|
||||
case 307: return "Temporary Redirect";
|
||||
case 308: return "Permanent Redirect";
|
||||
case 400: return "Bad Request";
|
||||
case 401: return "Unauthorized";
|
||||
case 402: return "Payment Required";
|
||||
case 403: return "Forbidden";
|
||||
case 404: return "Not Found";
|
||||
case 405: return "Method Not Allowed";
|
||||
case 406: return "Not Acceptable";
|
||||
case 407: return "Proxy Authentication Required";
|
||||
case 408: return "Request Timeout";
|
||||
case 409: return "Conflict";
|
||||
case 410: return "Gone";
|
||||
case 411: return "Length Required";
|
||||
case 412: return "Precondition Failed";
|
||||
case 413: return "Payload Too Large";
|
||||
case 414: return "Request-URI Too Long";
|
||||
case 415: return "Unsupported Media Type";
|
||||
case 416: return "Requested Range Not Satisfiable";
|
||||
case 417: return "Expectation Failed";
|
||||
case 418: return "I'm a teapot";
|
||||
case 421: return "Misdirected Request";
|
||||
case 422: return "Unprocessable Entity";
|
||||
case 423: return "Locked";
|
||||
case 424: return "Failed Dependency";
|
||||
case 426: return "Upgrade Required";
|
||||
case 428: return "Precondition Required";
|
||||
case 429: return "Too Many Requests";
|
||||
case 431: return "Request Header Fields Too Large";
|
||||
case 444: return "Connection Closed Without Response";
|
||||
case 451: return "Unavailable For Legal Reasons";
|
||||
case 499: return "Client Closed Request";
|
||||
case 500: return "Internal Server Error";
|
||||
case 501: return "Not Implemented";
|
||||
case 502: return "Bad Gateway";
|
||||
case 503: return "Service Unavailable";
|
||||
case 504: return "Gateway Timeout";
|
||||
case 505: return "HTTP Version Not Supported";
|
||||
case 506: return "Variant Also Negotiates";
|
||||
case 507: return "Insufficient Storage";
|
||||
case 508: return "Loop Detected";
|
||||
case 510: return "Not Extended";
|
||||
case 511: return "Network Authentication Required";
|
||||
case 599: return "Network Connect Timeout Error";
|
||||
default: return "OK";
|
||||
}
|
||||
}
|
||||
@@ -582,7 +534,7 @@ static void printdirentry(const char *name, void *userdata) {
|
||||
|
||||
static void listdir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
const struct mg_http_serve_opts *opts, char *dir) {
|
||||
static const char *sort_js_code =
|
||||
const char *sort_js_code =
|
||||
"<script>function srt(tb, sc, so, d) {"
|
||||
"var tr = Array.prototype.slice.call(tb.rows, 0),"
|
||||
"tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
|
||||
@@ -592,7 +544,7 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
"return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
|
||||
"n1 ? parseInt(n2) - parseInt(n1) : "
|
||||
"c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
|
||||
static const char *sort_js_code2 =
|
||||
const char *sort_js_code2 =
|
||||
"for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
|
||||
"if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
|
||||
"};"
|
||||
|
||||
+4
-6
@@ -95,20 +95,18 @@ void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
|
||||
mg_send_u16(c, mg_htons((uint16_t) topic.len));
|
||||
mg_send(c, topic.ptr, topic.len);
|
||||
if (qos > 0) {
|
||||
static uint16_t s_id;
|
||||
if (++s_id == 0) s_id++;
|
||||
mg_send_u16(c, mg_htons(s_id));
|
||||
if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
|
||||
mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
|
||||
}
|
||||
mg_send(c, data.ptr, data.len);
|
||||
}
|
||||
|
||||
void mg_mqtt_sub(struct mg_connection *c, struct mg_str topic, int qos) {
|
||||
static uint16_t s_id;
|
||||
uint8_t qos_ = qos & 3;
|
||||
uint32_t total_len = 2 + (uint32_t) topic.len + 2 + 1;
|
||||
mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, total_len);
|
||||
if (++s_id == 0) ++s_id;
|
||||
mg_send_u16(c, mg_htons(s_id));
|
||||
if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
|
||||
mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
|
||||
mg_send_u16(c, mg_htons((uint16_t) topic.len));
|
||||
mg_send(c, topic.ptr, topic.len);
|
||||
mg_send(c, &qos_, sizeof(qos_));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "net.h"
|
||||
#include "dns.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "tls.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -204,8 +205,17 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||
return t;
|
||||
}
|
||||
|
||||
void mg_mgr_free(struct mg_mgr *mgr) {
|
||||
struct mg_connection *c;
|
||||
struct mg_timer *tmp, *t = mgr->timers;
|
||||
while (t != NULL) tmp = t->next, free(t), t = tmp;
|
||||
for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
|
||||
mg_mgr_poll(mgr, 0);
|
||||
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "event.h"
|
||||
#include "iobuf.h"
|
||||
#include "str.h"
|
||||
#include "timer.h"
|
||||
|
||||
struct mg_dns {
|
||||
const char *url; // DNS server URL
|
||||
@@ -24,6 +25,9 @@ struct mg_mgr {
|
||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||
unsigned long nextid; // Next connection ID
|
||||
void *userdata; // Arbitrary user data pointer
|
||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||
void *active_dns_requests; // DNS requests in progress
|
||||
struct mg_timer *timers; // Active timers
|
||||
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
||||
#endif
|
||||
@@ -83,3 +87,5 @@ bool mg_mgr_wakeup(struct mg_connection *pipe, const void *buf, size_t len);
|
||||
struct mg_connection *mg_alloc_conn(struct mg_mgr *);
|
||||
void mg_close_conn(struct mg_connection *c);
|
||||
bool mg_open_listener(struct mg_connection *c, const char *url);
|
||||
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg);
|
||||
+1
-1
@@ -536,7 +536,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
|
||||
mg_iotest(mgr, ms);
|
||||
now = mg_millis();
|
||||
mg_timer_poll(now);
|
||||
mg_timer_poll(&mgr->timers, now);
|
||||
|
||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||
tmp = c->next;
|
||||
|
||||
@@ -194,7 +194,7 @@ char *mg_hexdump(const void *buf, size_t len) {
|
||||
|
||||
char *mg_hex(const void *buf, size_t len, char *to) {
|
||||
const unsigned char *p = (const unsigned char *) buf;
|
||||
static const char *hex = "0123456789abcdef";
|
||||
const char *hex = "0123456789abcdef";
|
||||
size_t i = 0;
|
||||
for (; len--; p++) {
|
||||
to[i++] = hex[p[0] >> 4];
|
||||
@@ -261,7 +261,6 @@ uint64_t mg_tou64(struct mg_str str) {
|
||||
while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||
result *= 10;
|
||||
result += (unsigned) (str.ptr[i] - '0');
|
||||
MG_INFO(("[%.*s] %llu", (int) str.len, str.ptr, result));
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
|
||||
+10
-17
@@ -4,33 +4,26 @@
|
||||
#include "timer.h"
|
||||
#include "arch.h"
|
||||
|
||||
struct mg_timer *g_timers;
|
||||
|
||||
void mg_timer_init(struct mg_timer *t, uint64_t ms, unsigned flags,
|
||||
void (*fn)(void *), void *arg) {
|
||||
struct mg_timer tmp = {ms, 0UL, flags, fn, arg, g_timers};
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer tmp = {ms, 0U, 0U, flags, fn, arg, *head};
|
||||
*t = tmp;
|
||||
g_timers = t;
|
||||
*head = t;
|
||||
if (flags & MG_TIMER_RUN_NOW) fn(arg);
|
||||
}
|
||||
|
||||
void mg_timer_free(struct mg_timer *t) {
|
||||
struct mg_timer **head = &g_timers;
|
||||
void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
|
||||
while (*head && *head != t) head = &(*head)->next;
|
||||
if (*head) *head = t->next;
|
||||
}
|
||||
|
||||
void mg_timer_poll(uint64_t now_ms) {
|
||||
void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
||||
// If time goes back (wrapped around), reset timers
|
||||
struct mg_timer *t, *tmp;
|
||||
static uint64_t oldnow; // Timestamp in a previous invocation
|
||||
if (oldnow > now_ms) { // If it is wrapped, reset timers
|
||||
for (t = g_timers; t != NULL; t = t->next) t->expire = 0;
|
||||
}
|
||||
oldnow = now_ms;
|
||||
|
||||
for (t = g_timers; t != NULL; t = tmp) {
|
||||
for (t = *head; t != NULL; t = tmp) {
|
||||
tmp = t->next;
|
||||
if (t->prev_ms > now_ms) t->expire = 0; // Handle time wrap
|
||||
t->prev_ms = now_ms;
|
||||
if (t->expire == 0) t->expire = now_ms + t->period_ms;
|
||||
if (t->expire > now_ms) continue;
|
||||
t->fn(t->arg);
|
||||
@@ -38,6 +31,6 @@ void mg_timer_poll(uint64_t now_ms) {
|
||||
// even if this polling function is called with some random period.
|
||||
t->expire = now_ms - t->expire > t->period_ms ? now_ms + t->period_ms
|
||||
: t->expire + t->period_ms;
|
||||
if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(t);
|
||||
if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(head, t);
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -4,6 +4,7 @@
|
||||
|
||||
struct mg_timer {
|
||||
uint64_t period_ms; // Timer period in milliseconds
|
||||
uint64_t prev_ms; // Timestamp of a previous poll
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
||||
@@ -15,7 +16,8 @@ struct mg_timer {
|
||||
|
||||
extern struct mg_timer *g_timers; // Global list of timers
|
||||
|
||||
void mg_timer_init(struct mg_timer *, uint64_t, unsigned, void (*)(void *),
|
||||
void *);
|
||||
void mg_timer_free(struct mg_timer *);
|
||||
void mg_timer_poll(uint64_t current_time_ms);
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
||||
uint64_t milliseconds, unsigned flags, void (*fn)(void *),
|
||||
void *arg);
|
||||
void mg_timer_free(struct mg_timer **head, struct mg_timer *);
|
||||
void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
|
||||
Reference in new issue
Block a user