mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 15:01:03 +08:00
Remove mg_enable_multithreading. Close cesanta/dev#6511
PUBLISHED_FROM=7864ffa26cb553f5d4a93248f67c288327ec23b0
This commit is contained in:
parent
cd6b846e22
commit
707b9ed2d6
@ -12,7 +12,6 @@ items:
|
||||
- { name: mg_connect.md }
|
||||
- { name: mg_connect_opt.md }
|
||||
- { name: mg_enable_javascript.md }
|
||||
- { name: mg_enable_multithreading.md }
|
||||
- { name: mg_mgr_free.md }
|
||||
- { name: mg_mgr_init.md }
|
||||
- { name: mg_mgr_init_opt.md }
|
||||
@ -33,7 +32,6 @@ items:
|
||||
- { name: struct_mg_connection.md }
|
||||
- { name: struct_mg_mgr.md }
|
||||
- { name: struct_mg_mgr_init_opts.md }
|
||||
- { name: struct_mg_multithreading_opts.md }
|
||||
---
|
||||
|
||||
NOTE: Mongoose manager is single threaded. It does not protect
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
title: "mg_enable_multithreading()"
|
||||
decl_name: "mg_enable_multithreading"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_enable_multithreading(struct mg_connection *nc);
|
||||
---
|
||||
|
||||
Enables multi-threaded handling for the given listening connection `nc`.
|
||||
For each accepted connection, Mongoose will create a separate thread
|
||||
and run an event handler in that thread. Thus, if an event handler is doing
|
||||
a blocking call or some long computation, it will not slow down
|
||||
other connections.
|
||||
|
@ -31,8 +31,8 @@ signature: |
|
||||
* void pointers, since some archs might have fat pointers for functions.
|
||||
*/
|
||||
mg_event_handler_t f;
|
||||
} priv_1; /* Used by mg_enable_multithreading() */
|
||||
void *priv_2; /* Used by mg_enable_multithreading() */
|
||||
} priv_1;
|
||||
void *priv_2;
|
||||
void *mgr_data; /* Implementation-specific event manager's data. */
|
||||
struct mg_iface *iface;
|
||||
unsigned long flags;
|
||||
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
title: "struct mg_multithreading_opts"
|
||||
decl_name: "struct mg_multithreading_opts"
|
||||
symbol_kind: "struct"
|
||||
signature: |
|
||||
struct mg_multithreading_opts {
|
||||
int poll_timeout; /* Polling interval */
|
||||
};
|
||||
---
|
||||
|
||||
Optional parameters for mg_enable_multithreading_opt()
|
||||
|
@ -1,4 +0,0 @@
|
||||
PROG = multithreaded_restful_server
|
||||
MODULE_CFLAGS = -DMG_ENABLE_THREADS
|
||||
SSL_LIB=openssl
|
||||
include ../examples.mk
|
@ -1,53 +0,0 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
// This example shows how to handle long, blocking requests by
|
||||
// handing off computation to different threads. Here, each
|
||||
// request spawns a new thread. In a production scenario, a thread
|
||||
// pools can be used for efficiency, if required.
|
||||
// Long computation is simulated by sleeping for a random interval.
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
|
||||
static void ev_handler(struct mg_connection *c, int ev, void *p) {
|
||||
if (ev == MG_EV_HTTP_REQUEST) {
|
||||
struct http_message *hm = (struct http_message *) p;
|
||||
char reply[100];
|
||||
|
||||
/* Simulate long calculation */
|
||||
sleep(3);
|
||||
|
||||
/* Send the reply */
|
||||
snprintf(reply, sizeof(reply), "{ \"uri\": \"%.*s\" }\n", (int) hm->uri.len,
|
||||
hm->uri.p);
|
||||
mg_printf(c,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
(int) strlen(reply), reply);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
|
||||
/* For each new connection, execute ev_handler in a separate thread */
|
||||
mg_enable_multithreading(nc);
|
||||
|
||||
printf("Starting multi-threaded server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 3000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
133
mongoose.c
133
mongoose.c
@ -4627,139 +4627,6 @@ int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len) {
|
||||
|
||||
#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS */
|
||||
#ifdef MG_MODULE_LINES
|
||||
#line 1 "mongoose/src/multithreading.c"
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 2014 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*/
|
||||
|
||||
/* Amalgamated: #include "mongoose/src/internal.h" */
|
||||
/* Amalgamated: #include "mongoose/src/util.h" */
|
||||
|
||||
#if MG_ENABLE_THREADS
|
||||
|
||||
static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p);
|
||||
|
||||
/*
|
||||
* This thread function executes user event handler.
|
||||
* It runs an event manager that has only one connection, until that
|
||||
* connection is alive.
|
||||
*/
|
||||
static void *per_connection_thread_function(void *param) {
|
||||
struct mg_connection *c = (struct mg_connection *) param;
|
||||
struct mg_mgr m;
|
||||
/* mgr_data can be used subsequently, store its value */
|
||||
int poll_timeout = (intptr_t) c->mgr_data;
|
||||
|
||||
mg_mgr_init(&m, NULL);
|
||||
mg_add_conn(&m, c);
|
||||
mg_call(c, NULL, MG_EV_ACCEPT, &c->sa);
|
||||
|
||||
while (m.active_connections != NULL) {
|
||||
mg_mgr_poll(&m, poll_timeout ? poll_timeout : 1000);
|
||||
}
|
||||
mg_mgr_free(&m);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
static void link_conns(struct mg_connection *c1, struct mg_connection *c2) {
|
||||
c1->priv_2 = c2;
|
||||
c2->priv_2 = c1;
|
||||
}
|
||||
|
||||
static void unlink_conns(struct mg_connection *c) {
|
||||
struct mg_connection *peer = (struct mg_connection *) c->priv_2;
|
||||
if (peer != NULL) {
|
||||
peer->flags |= MG_F_SEND_AND_CLOSE;
|
||||
peer->priv_2 = NULL;
|
||||
}
|
||||
c->priv_2 = NULL;
|
||||
}
|
||||
|
||||
static void forwarder_ev_handler(struct mg_connection *c, int ev, void *p) {
|
||||
(void) p;
|
||||
if (ev == MG_EV_RECV && c->priv_2) {
|
||||
mg_forward(c, (struct mg_connection *) c->priv_2);
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
unlink_conns(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void spawn_handling_thread(struct mg_connection *nc) {
|
||||
struct mg_mgr dummy;
|
||||
sock_t sp[2];
|
||||
struct mg_connection *c[2];
|
||||
int poll_timeout;
|
||||
/*
|
||||
* Create a socket pair, and wrap each socket into the connection with
|
||||
* dummy event manager.
|
||||
* c[0] stays in this thread, c[1] goes to another thread.
|
||||
*/
|
||||
mg_mgr_init(&dummy, NULL);
|
||||
mg_socketpair(sp, SOCK_STREAM);
|
||||
|
||||
c[0] = mg_add_sock(&dummy, sp[0], forwarder_ev_handler);
|
||||
c[1] = mg_add_sock(&dummy, sp[1], nc->listener->priv_1.f);
|
||||
|
||||
/* link_conns replaces priv_2, storing its value */
|
||||
poll_timeout = (intptr_t) nc->priv_2;
|
||||
|
||||
/* Interlink client connection with c[0] */
|
||||
link_conns(c[0], nc);
|
||||
|
||||
/*
|
||||
* Switch c[0] manager from the dummy one to the real one. c[1] manager
|
||||
* will be set in another thread, allocated on stack of that thread.
|
||||
*/
|
||||
mg_add_conn(nc->mgr, c[0]);
|
||||
|
||||
/*
|
||||
* Dress c[1] as nc.
|
||||
* TODO(lsm): code in accept_conn() looks similar. Refactor.
|
||||
*/
|
||||
c[1]->listener = nc->listener;
|
||||
c[1]->proto_handler = nc->proto_handler;
|
||||
c[1]->user_data = nc->user_data;
|
||||
c[1]->sa = nc->sa;
|
||||
c[1]->flags = nc->flags;
|
||||
|
||||
/* priv_2 is used, so, put timeout to mgr_data */
|
||||
c[1]->mgr_data = (void *) (intptr_t) poll_timeout;
|
||||
|
||||
mg_start_thread(per_connection_thread_function, c[1]);
|
||||
}
|
||||
|
||||
static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p) {
|
||||
(void) p;
|
||||
if (ev == MG_EV_ACCEPT) {
|
||||
spawn_handling_thread(c);
|
||||
c->handler = forwarder_ev_handler;
|
||||
}
|
||||
}
|
||||
|
||||
void mg_enable_multithreading_opt(struct mg_connection *nc,
|
||||
struct mg_multithreading_opts opts) {
|
||||
/* Wrap user event handler into our multithreaded_ev_handler */
|
||||
nc->priv_1.f = nc->handler;
|
||||
/*
|
||||
* We put timeout to `priv_2` member of the main
|
||||
* (listening) connection, mt is not enabled yet,
|
||||
* and this member is not used
|
||||
*/
|
||||
nc->priv_2 = (void *) (intptr_t) opts.poll_timeout;
|
||||
nc->handler = multithreaded_ev_handler;
|
||||
}
|
||||
|
||||
void mg_enable_multithreading(struct mg_connection *nc) {
|
||||
struct mg_multithreading_opts opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
mg_enable_multithreading_opt(nc, opts);
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef MG_MODULE_LINES
|
||||
#line 1 "mongoose/src/uri.c"
|
||||
#endif
|
||||
/*
|
||||
|
22
mongoose.h
22
mongoose.h
@ -3281,8 +3281,8 @@ struct mg_connection {
|
||||
* void pointers, since some archs might have fat pointers for functions.
|
||||
*/
|
||||
mg_event_handler_t f;
|
||||
} priv_1; /* Used by mg_enable_multithreading() */
|
||||
void *priv_2; /* Used by mg_enable_multithreading() */
|
||||
} priv_1;
|
||||
void *priv_2;
|
||||
void *mgr_data; /* Implementation-specific event manager's data. */
|
||||
struct mg_iface *iface;
|
||||
unsigned long flags;
|
||||
@ -3692,24 +3692,6 @@ int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
|
||||
*/
|
||||
int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
|
||||
|
||||
/*
|
||||
* Optional parameters for mg_enable_multithreading_opt()
|
||||
*/
|
||||
struct mg_multithreading_opts {
|
||||
int poll_timeout; /* Polling interval */
|
||||
};
|
||||
|
||||
/*
|
||||
* Enables multi-threaded handling for the given listening connection `nc`.
|
||||
* For each accepted connection, Mongoose will create a separate thread
|
||||
* and run an event handler in that thread. Thus, if an event handler is doing
|
||||
* a blocking call or some long computation, it will not slow down
|
||||
* other connections.
|
||||
*/
|
||||
void mg_enable_multithreading(struct mg_connection *nc);
|
||||
void mg_enable_multithreading_opt(struct mg_connection *nc,
|
||||
struct mg_multithreading_opts opts);
|
||||
|
||||
#if MG_ENABLE_JAVASCRIPT
|
||||
/*
|
||||
* Enables server-side JavaScript scripting.
|
||||
|
Loading…
x
Reference in New Issue
Block a user