moonbridge
changeset 127:37532927dba9
Introduced new proto "main" to allow for a main thread
author | jbe |
---|---|
date | Tue Apr 14 19:30:53 2015 +0200 (2015-04-14) |
parents | e0ab9fd00cb1 |
children | ebaac38b7224 |
files | helloworld.lua moonbridge.c |
line diff
1.1 --- a/helloworld.lua Tue Apr 14 18:20:39 2015 +0200 1.2 +++ b/helloworld.lua Tue Apr 14 19:30:53 2015 +0200 1.3 @@ -6,6 +6,13 @@ 1.4 local http = require "moonbridge_http" 1.5 1.6 listen{ 1.7 + { proto = "main" }, 1.8 + connect = function() 1.9 + print("Main function executed") 1.10 + end 1.11 +} 1.12 + 1.13 +listen{ 1.14 { proto = "tcp", host = "127.0.0.1", port = 8080 }, -- IPv4 1.15 { proto = "tcp", host = "::1", port = 8080 }, -- IPv6 1.16 connect = http.generate_handler(
2.1 --- a/moonbridge.c Tue Apr 14 18:20:39 2015 +0200 2.2 +++ b/moonbridge.c Tue Apr 14 19:30:53 2015 +0200 2.3 @@ -123,9 +123,10 @@ 2.4 #define MOONBR_PSTATE_FORKED 2 2.5 2.6 /* Enum for 'proto' field of struct moonbr_listener */ 2.7 -#define MOONBR_PROTO_INTERVAL 1 2.8 -#define MOONBR_PROTO_LOCAL 2 2.9 -#define MOONBR_PROTO_TCP 3 2.10 +#define MOONBR_PROTO_MAIN 1 2.11 +#define MOONBR_PROTO_INTERVAL 2 2.12 +#define MOONBR_PROTO_LOCAL 3 2.13 +#define MOONBR_PROTO_TCP 4 2.14 2.15 /* Data structure for a pool's listener that can accept incoming connections */ 2.16 struct moonbr_listener { 2.17 @@ -167,6 +168,7 @@ 2.18 struct moonbr_worker *next_worker; 2.19 struct moonbr_worker *prev_idle_worker; 2.20 struct moonbr_worker *next_idle_worker; 2.21 + int main; /* nonzero = terminate Moonbridge when this worker dies */ 2.22 int idle; /* nonzero = waiting for command from parent process */ 2.23 int assigned; /* nonzero = currently handling a connection */ 2.24 pid_t pid; 2.25 @@ -513,6 +515,10 @@ 2.26 for (i=0; i<pool->listener_count; i++) { 2.27 struct moonbr_listener *listener = &pool->listener[i]; 2.28 switch (listener->proto) { 2.29 + case MOONBR_PROTO_MAIN: 2.30 + /* nothing to do here: starting main thread is performed in moonbr_run() function */ 2.31 + moonbr_log(LOG_INFO, "Adding main thread"); 2.32 + break; 2.33 case MOONBR_PROTO_INTERVAL: 2.34 /* nothing to do here: starting intervals is performed in moonbr_run() function */ 2.35 if (!listener->type_specific.interval.name) { 2.36 @@ -771,9 +777,17 @@ 2.37 } 2.38 if (controlmsg == MOONBR_COMMAND_TERMINATE) break; 2.39 listener = moonbr_child_receive_pointer(MOONBR_FD_CONTROL); 2.40 - if (listener->proto == MOONBR_PROTO_INTERVAL && fd >= 0) { 2.41 + if ( 2.42 + listener->proto != MOONBR_PROTO_LOCAL && 2.43 + listener->proto != MOONBR_PROTO_TCP && 2.44 + fd >= 0 2.45 + ) { 2.46 moonbr_child_log_fatal("Received unexpected file descriptor from parent process"); 2.47 - } else if (listener->proto != MOONBR_PROTO_INTERVAL && fd < 0) { 2.48 + } else if ( 2.49 + listener->proto != MOONBR_PROTO_MAIN && 2.50 + listener->proto != MOONBR_PROTO_INTERVAL && 2.51 + fd < 0 2.52 + ) { 2.53 moonbr_child_log_fatal("Missing file descriptor from parent process"); 2.54 } 2.55 if (fd >= 0) moonbr_io_pushhandle(L, fd); 2.56 @@ -1000,6 +1014,7 @@ 2.57 MOONBR_DESTROY_IDLE_OR_ASSIGNED : 2.58 MOONBR_DESTROY_PREPARE 2.59 ); 2.60 + //if (worker->main) moonbr_initiate_shutdown(); // TODO 2.61 if (worker->prev_worker) worker->prev_worker->next_worker = worker->next_worker; 2.62 else worker->pool->first_worker = worker->next_worker; 2.63 if (worker->next_worker) worker->next_worker->prev_worker = worker->prev_worker; 2.64 @@ -1396,7 +1411,15 @@ 2.65 static void moonbr_connect(struct moonbr_pool *pool) { 2.66 struct moonbr_listener *listener = moonbr_pop_connected_listener(pool); 2.67 struct moonbr_worker *worker; 2.68 - if (listener->proto == MOONBR_PROTO_INTERVAL) { 2.69 + if (listener->proto == MOONBR_PROTO_MAIN) { 2.70 + worker = moonbr_pop_idle_worker(pool); 2.71 + if (moonbr_stat) { 2.72 + moonbr_log(LOG_INFO, "Dispatching main thread of pool #%i to PID %i", listener->pool->poolnum, (int)worker->pid); 2.73 + } 2.74 + worker->main = 1; 2.75 + moonbr_send_control_message(worker, MOONBR_COMMAND_CONNECT, -1, listener); 2.76 + /* do not push listener to queue of idle listeners */ 2.77 + } else if (listener->proto == MOONBR_PROTO_INTERVAL) { 2.78 worker = moonbr_pop_idle_worker(pool); 2.79 if (moonbr_stat) { 2.80 moonbr_log(LOG_INFO, "Dispatching interval timer \"%s\" of pool #%i to PID %i", listener->type_specific.interval.name, listener->pool->poolnum, (int)worker->pid); 2.81 @@ -1537,14 +1560,12 @@ 2.82 moonbr_remove_idle_listener(listener); 2.83 moonbr_add_connected_listener(listener); 2.84 } 2.85 - } else if (listener->proto == MOONBR_PROTO_INTERVAL) { 2.86 - if (!timercmp(&listener->type_specific.interval.wakeup, &now, >)) { 2.87 - moonbr_remove_idle_listener(listener); 2.88 - moonbr_add_connected_listener(listener); 2.89 - } 2.90 - } else { 2.91 - moonbr_log(LOG_CRIT, "Internal error (should not happen): Listener is neither an interval timer nor has the 'pollidx' value set"); 2.92 - moonbr_terminate_error(); 2.93 + } else if ( 2.94 + listener->proto != MOONBR_PROTO_INTERVAL || 2.95 + !timercmp(&listener->type_specific.interval.wakeup, &now, >) 2.96 + ) { 2.97 + moonbr_remove_idle_listener(listener); 2.98 + moonbr_add_connected_listener(listener); 2.99 } 2.100 } 2.101 /* process input from child processes */ 2.102 @@ -1856,6 +1877,7 @@ 2.103 struct moonbr_pool *pool; 2.104 const char *proto; 2.105 int i; 2.106 + int dynamic = 0; /* nonzero = listeners exist which require dynamic worker creation */ 2.107 pool = lua_touserdata(L, 1); 2.108 for (i=0; i<pool->listener_count; i++) { 2.109 struct moonbr_listener *listener = &pool->listener[i]; 2.110 @@ -1868,7 +1890,10 @@ 2.111 #endif 2.112 lua_getfield(L, 3, "proto"); 2.113 proto = lua_tostring(L, -1); 2.114 - if (proto && !strcmp(proto, "interval")) { 2.115 + if (proto && !strcmp(proto, "main")) { 2.116 + listener->proto = MOONBR_PROTO_MAIN; 2.117 + } else if (proto && !strcmp(proto, "interval")) { 2.118 + dynamic = 1; 2.119 listener->proto = MOONBR_PROTO_INTERVAL; 2.120 lua_getfield(L, 3, "name"); 2.121 { 2.122 @@ -1901,6 +1926,7 @@ 2.123 sizeof(listener->type_specific.socket.addr.addr_un) - 2.124 ((void *)listener->type_specific.socket.addr.addr_un.sun_path - (void *)&listener->type_specific.socket.addr.addr_un) 2.125 ) - 1; /* one byte for termination */ 2.126 + dynamic = 1; 2.127 listener->proto = MOONBR_PROTO_LOCAL; 2.128 lua_getfield(L, 3, "path"); 2.129 path = lua_tostring(L, -1); 2.130 @@ -1917,6 +1943,7 @@ 2.131 struct addrinfo *res, *addrinfo; 2.132 int errcode; 2.133 const char *ip; 2.134 + dynamic = 1; 2.135 lua_getfield(L, 3, "host"); 2.136 host = lua_isnil(L, -1) ? "::" : lua_tostring(L, -1); 2.137 if (!host) { 2.138 @@ -1995,23 +2022,29 @@ 2.139 } 2.140 } 2.141 lua_settop(L, 2); 2.142 - moonbr_listen_init_pool_forkoption("pre_fork", pre_fork, 1); 2.143 - moonbr_listen_init_pool_forkoption("min_fork", min_fork, pool->pre_fork > 2 ? pool->pre_fork : 2); 2.144 - moonbr_listen_init_pool_forkoption("max_fork", max_fork, pool->min_fork > 16 ? pool->min_fork : 16); 2.145 - if (!moonbr_listen_init_pool_timeoption("fork_delay", fork_delay, 0, 250000)) { 2.146 - luaL_error(L, "Option \"fork_delay\" is expected to be a non-negative number"); 2.147 - } 2.148 - if (!moonbr_listen_init_pool_timeoption("fork_error_delay", fork_error_delay, 2, 0)) { 2.149 - luaL_error(L, "Option \"fork_error_delay\" is expected to be a non-negative number"); 2.150 - } 2.151 - if (!moonbr_listen_init_pool_timeoption("exit_delay", exit_delay, 60, 0)) { 2.152 - luaL_error(L, "Option \"exit_delay\" is expected to be a non-negative number"); 2.153 - } 2.154 - if (timercmp(&pool->fork_error_delay, &pool->fork_delay, <)) { 2.155 - pool->fork_error_delay = pool->fork_delay; 2.156 - } 2.157 - if (!moonbr_listen_init_pool_timeoption("idle_timeout", idle_timeout, 0, 0)) { 2.158 - luaL_error(L, "Option \"idle_timeout\" is expected to be a non-negative number"); 2.159 + if (dynamic) { 2.160 + moonbr_listen_init_pool_forkoption("pre_fork", pre_fork, 1); 2.161 + moonbr_listen_init_pool_forkoption("min_fork", min_fork, pool->pre_fork > 2 ? pool->pre_fork : 2); 2.162 + moonbr_listen_init_pool_forkoption("max_fork", max_fork, pool->min_fork > 16 ? pool->min_fork : 16); 2.163 + if (!moonbr_listen_init_pool_timeoption("fork_delay", fork_delay, 0, 250000)) { 2.164 + luaL_error(L, "Option \"fork_delay\" is expected to be a non-negative number"); 2.165 + } 2.166 + if (!moonbr_listen_init_pool_timeoption("fork_error_delay", fork_error_delay, 2, 0)) { 2.167 + luaL_error(L, "Option \"fork_error_delay\" is expected to be a non-negative number"); 2.168 + } 2.169 + if (!moonbr_listen_init_pool_timeoption("exit_delay", exit_delay, 60, 0)) { 2.170 + luaL_error(L, "Option \"exit_delay\" is expected to be a non-negative number"); 2.171 + } 2.172 + if (timercmp(&pool->fork_error_delay, &pool->fork_delay, <)) { 2.173 + pool->fork_error_delay = pool->fork_delay; 2.174 + } 2.175 + if (!moonbr_listen_init_pool_timeoption("idle_timeout", idle_timeout, 0, 0)) { 2.176 + luaL_error(L, "Option \"idle_timeout\" is expected to be a non-negative number"); 2.177 + } 2.178 + } else { 2.179 + pool->pre_fork = 0; 2.180 + pool->min_fork = pool->listener_count; 2.181 + pool->max_fork = pool->listener_count; 2.182 } 2.183 lua_getfield(L, 2, "memory_limit"); 2.184 if (!lua_isnil(L, -1)) {