Use user timeout in multithreading polling

PUBLISHED_FROM=dbf75bfba087f1b0aa0531e5003ba3e69ed1a6ab
This commit is contained in:
Alexander Alashkin 2016-09-12 15:09:35 +01:00 committed by Cesanta Bot
parent d9b7ec18e7
commit 4cbf81da59
4 changed files with 49 additions and 3 deletions

View File

@ -30,6 +30,7 @@ items:
- { name: struct_mg_add_sock_opts.md } - { name: struct_mg_add_sock_opts.md }
- { name: struct_mg_bind_opts.md } - { name: struct_mg_bind_opts.md }
- { name: struct_mg_connect_opts.md } - { name: struct_mg_connect_opts.md }
- { name: struct_mg_multithreading_opts.md }
--- ---
NOTE: Mongoose manager is single threaded. It does not protect NOTE: Mongoose manager is single threaded. It does not protect

View File

@ -0,0 +1,12 @@
---
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()

View File

@ -3456,13 +3456,15 @@ static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p);
static void *per_connection_thread_function(void *param) { static void *per_connection_thread_function(void *param) {
struct mg_connection *c = (struct mg_connection *) param; struct mg_connection *c = (struct mg_connection *) param;
struct mg_mgr m; 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_mgr_init(&m, NULL);
mg_add_conn(&m, c); mg_add_conn(&m, c);
mg_call(c, NULL, MG_EV_ACCEPT, &c->sa); mg_call(c, NULL, MG_EV_ACCEPT, &c->sa);
while (m.active_connections != NULL) { while (m.active_connections != NULL) {
mg_mgr_poll(&m, 1000); mg_mgr_poll(&m, poll_timeout ? poll_timeout : 1000);
} }
mg_mgr_free(&m); mg_mgr_free(&m);
@ -3496,7 +3498,7 @@ static void spawn_handling_thread(struct mg_connection *nc) {
struct mg_mgr dummy; struct mg_mgr dummy;
sock_t sp[2]; sock_t sp[2];
struct mg_connection *c[2]; struct mg_connection *c[2];
int poll_timeout;
/* /*
* Create a socket pair, and wrap each socket into the connection with * Create a socket pair, and wrap each socket into the connection with
* dummy event manager. * dummy event manager.
@ -3507,6 +3509,9 @@ static void spawn_handling_thread(struct mg_connection *nc) {
c[0] = mg_add_sock(&dummy, sp[0], forwarder_ev_handler); c[0] = mg_add_sock(&dummy, sp[0], forwarder_ev_handler);
c[1] = mg_add_sock(&dummy, sp[1], nc->listener->priv_1.f); 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] */ /* Interlink client connection with c[0] */
link_conns(c[0], nc); link_conns(c[0], nc);
@ -3526,6 +3531,9 @@ static void spawn_handling_thread(struct mg_connection *nc) {
c[1]->sa = nc->sa; c[1]->sa = nc->sa;
c[1]->flags = nc->flags; 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]); mg_start_thread(per_connection_thread_function, c[1]);
} }
@ -3537,11 +3545,25 @@ static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p) {
} }
} }
void mg_enable_multithreading(struct mg_connection *nc) { void mg_enable_multithreading_opt(struct mg_connection *nc,
struct mg_multithreading_opts opts) {
/* Wrap user event handler into our multithreaded_ev_handler */ /* Wrap user event handler into our multithreaded_ev_handler */
nc->priv_1.f = nc->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; 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 #endif
#ifdef MG_MODULE_LINES #ifdef MG_MODULE_LINES
#line 1 "./src/uri.c" #line 1 "./src/uri.c"

View File

@ -189,6 +189,7 @@
#endif #endif
#if defined(_MSC_VER) && _MSC_VER <= 1200 #if defined(_MSC_VER) && _MSC_VER <= 1200
typedef unsigned long uintptr_t; typedef unsigned long uintptr_t;
typedef long intptr_t;
#endif #endif
typedef int socklen_t; typedef int socklen_t;
#if _MSC_VER >= 1700 #if _MSC_VER >= 1700
@ -287,6 +288,7 @@ typedef struct _stati64 cs_stat_t;
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdint.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <netdb.h> #include <netdb.h>
@ -1583,6 +1585,13 @@ 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); 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`. * Enables multi-threaded handling for the given listening connection `nc`.
* For each accepted connection, Mongoose will create a separate thread * For each accepted connection, Mongoose will create a separate thread
@ -1591,6 +1600,8 @@ int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
* other connections. * other connections.
*/ */
void mg_enable_multithreading(struct mg_connection *nc); void mg_enable_multithreading(struct mg_connection *nc);
void mg_enable_multithreading_opt(struct mg_connection *nc,
struct mg_multithreading_opts opts);
#ifdef MG_ENABLE_JAVASCRIPT #ifdef MG_ENABLE_JAVASCRIPT
/* /*