mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-02 13:20:51 +00:00
Add mg_wakeup()
This commit is contained in:
1 parent
669ffe2c74
commit
61825b2390
7 files changed
+216
-67
No files matched your search
@@ -25,5 +25,6 @@ enum {
|
||||
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
||||
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
||||
MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis
|
||||
MG_EV_WAKEUP, // mg_wakeup() data received struct mg_str *data
|
||||
MG_EV_USER // Starting ID for user events
|
||||
};
|
||||
@@ -271,6 +271,7 @@ void mg_mgr_init(struct mg_mgr *mgr) {
|
||||
// won't kill the whole process.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
mgr->pipe = MG_INVALID_SOCKET;
|
||||
mgr->dnstimeout = 3000;
|
||||
mgr->dns4.url = "udp://8.8.8.8:53";
|
||||
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
||||
|
||||
@@ -35,6 +35,7 @@ struct mg_mgr {
|
||||
int epoll_fd; // Used when MG_EPOLL_ENABLE=1
|
||||
void *priv; // Used by the MIP stack
|
||||
size_t extraconnsize; // Used by the MIP stack
|
||||
MG_SOCKET_TYPE pipe; // Socketpair end for mg_wakeup()
|
||||
#if MG_ENABLE_FREERTOS_TCP
|
||||
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
||||
#endif
|
||||
@@ -99,5 +100,7 @@ void mg_close_conn(struct mg_connection *c);
|
||||
bool mg_open_listener(struct mg_connection *c, const char *url);
|
||||
|
||||
// Utility functions
|
||||
bool mg_wakeup(struct mg_mgr *, unsigned long id, const void *buf, size_t len);
|
||||
bool mg_wakeup_init(struct mg_mgr *);
|
||||
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg);
|
||||
+86
@@ -589,6 +589,92 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool mg_socketpair(MG_SOCKET_TYPE sp[2], union usa usa[2]) {
|
||||
socklen_t n = sizeof(usa[0].sin);
|
||||
bool success = false;
|
||||
|
||||
sp[0] = sp[1] = MG_INVALID_SOCKET;
|
||||
(void) memset(&usa[0], 0, sizeof(usa[0]));
|
||||
usa[0].sin.sin_family = AF_INET;
|
||||
*(uint32_t *) &usa->sin.sin_addr = mg_htonl(0x7f000001U); // 127.0.0.1
|
||||
usa[1] = usa[0];
|
||||
|
||||
if ((sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != MG_INVALID_SOCKET &&
|
||||
(sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != MG_INVALID_SOCKET &&
|
||||
bind(sp[0], &usa[0].sa, n) == 0 && //
|
||||
bind(sp[1], &usa[1].sa, n) == 0 && //
|
||||
getsockname(sp[0], &usa[0].sa, &n) == 0 && //
|
||||
getsockname(sp[1], &usa[1].sa, &n) == 0 && //
|
||||
connect(sp[0], &usa[1].sa, n) == 0 && //
|
||||
connect(sp[1], &usa[0].sa, n) == 0) { //
|
||||
success = true;
|
||||
}
|
||||
if (!success) {
|
||||
if (sp[0] != MG_INVALID_SOCKET) closesocket(sp[0]);
|
||||
if (sp[1] != MG_INVALID_SOCKET) closesocket(sp[1]);
|
||||
sp[0] = sp[1] = MG_INVALID_SOCKET;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// mg_wakeup() event handler
|
||||
static void wufn(struct mg_connection *c, int ev, void *evd, void *fnd) {
|
||||
if (ev == MG_EV_READ) {
|
||||
unsigned long *id = (unsigned long *) c->recv.buf;
|
||||
// MG_INFO(("Got data"));
|
||||
// mg_hexdump(c->recv.buf, c->recv.len);
|
||||
if (c->recv.len >= sizeof(*id)) {
|
||||
struct mg_connection *t;
|
||||
for (t = c->mgr->conns; t != NULL; t = t->next) {
|
||||
if (t->id == *id) {
|
||||
struct mg_str data = mg_str_n((char *) c->recv.buf + sizeof(*id),
|
||||
c->recv.len - sizeof(*id));
|
||||
mg_call(t, MG_EV_WAKEUP, &data);
|
||||
}
|
||||
}
|
||||
}
|
||||
c->recv.len = 0; // Consume received data
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
closesocket(c->mgr->pipe); // When we're closing, close the other
|
||||
c->mgr->pipe = MG_INVALID_SOCKET; // side of the socketpair, too
|
||||
}
|
||||
(void) evd, (void) fnd;
|
||||
}
|
||||
|
||||
bool mg_wakeup_init(struct mg_mgr *mgr) {
|
||||
bool ok = false;
|
||||
if (mgr->pipe == MG_INVALID_SOCKET) {
|
||||
union usa usa[2];
|
||||
MG_SOCKET_TYPE sp[2] = {MG_INVALID_SOCKET, MG_INVALID_SOCKET};
|
||||
struct mg_connection *c = NULL;
|
||||
if (!mg_socketpair(sp, usa)) {
|
||||
MG_ERROR(("Cannot create socket pair"));
|
||||
} else if ((c = mg_wrapfd(mgr, (int) sp[1], wufn, NULL)) == NULL) {
|
||||
closesocket(sp[0]);
|
||||
closesocket(sp[1]);
|
||||
sp[0] = sp[1] = MG_INVALID_SOCKET;
|
||||
} else {
|
||||
tomgaddr(&usa[0], &c->rem, false);
|
||||
MG_DEBUG(("%lu %p pipe %lu", c->id, c->fd, (unsigned long) sp[0]));
|
||||
mgr->pipe = sp[0];
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool mg_wakeup(struct mg_mgr *mgr, unsigned long conn_id, const void *buf,
|
||||
size_t len) {
|
||||
if (mgr->pipe != MG_INVALID_SOCKET && conn_id > 0) {
|
||||
char *extended_buf = (char *) alloca(len + sizeof(conn_id));
|
||||
memcpy(extended_buf, &conn_id, sizeof(conn_id));
|
||||
memcpy(extended_buf + sizeof(conn_id), buf, len);
|
||||
send(mgr->pipe, extended_buf, len + sizeof(conn_id), MSG_NONBLOCKING);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
struct mg_connection *c, *tmp;
|
||||
uint64_t now;
|
||||
|
||||
Reference in new issue
Block a user