moonbridge
diff moonbridge.c @ 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 |
line diff
1.1 --- a/moonbridge.c Tue Apr 14 18:20:39 2015 +0200 1.2 +++ b/moonbridge.c Tue Apr 14 19:30:53 2015 +0200 1.3 @@ -123,9 +123,10 @@ 1.4 #define MOONBR_PSTATE_FORKED 2 1.5 1.6 /* Enum for 'proto' field of struct moonbr_listener */ 1.7 -#define MOONBR_PROTO_INTERVAL 1 1.8 -#define MOONBR_PROTO_LOCAL 2 1.9 -#define MOONBR_PROTO_TCP 3 1.10 +#define MOONBR_PROTO_MAIN 1 1.11 +#define MOONBR_PROTO_INTERVAL 2 1.12 +#define MOONBR_PROTO_LOCAL 3 1.13 +#define MOONBR_PROTO_TCP 4 1.14 1.15 /* Data structure for a pool's listener that can accept incoming connections */ 1.16 struct moonbr_listener { 1.17 @@ -167,6 +168,7 @@ 1.18 struct moonbr_worker *next_worker; 1.19 struct moonbr_worker *prev_idle_worker; 1.20 struct moonbr_worker *next_idle_worker; 1.21 + int main; /* nonzero = terminate Moonbridge when this worker dies */ 1.22 int idle; /* nonzero = waiting for command from parent process */ 1.23 int assigned; /* nonzero = currently handling a connection */ 1.24 pid_t pid; 1.25 @@ -513,6 +515,10 @@ 1.26 for (i=0; i<pool->listener_count; i++) { 1.27 struct moonbr_listener *listener = &pool->listener[i]; 1.28 switch (listener->proto) { 1.29 + case MOONBR_PROTO_MAIN: 1.30 + /* nothing to do here: starting main thread is performed in moonbr_run() function */ 1.31 + moonbr_log(LOG_INFO, "Adding main thread"); 1.32 + break; 1.33 case MOONBR_PROTO_INTERVAL: 1.34 /* nothing to do here: starting intervals is performed in moonbr_run() function */ 1.35 if (!listener->type_specific.interval.name) { 1.36 @@ -771,9 +777,17 @@ 1.37 } 1.38 if (controlmsg == MOONBR_COMMAND_TERMINATE) break; 1.39 listener = moonbr_child_receive_pointer(MOONBR_FD_CONTROL); 1.40 - if (listener->proto == MOONBR_PROTO_INTERVAL && fd >= 0) { 1.41 + if ( 1.42 + listener->proto != MOONBR_PROTO_LOCAL && 1.43 + listener->proto != MOONBR_PROTO_TCP && 1.44 + fd >= 0 1.45 + ) { 1.46 moonbr_child_log_fatal("Received unexpected file descriptor from parent process"); 1.47 - } else if (listener->proto != MOONBR_PROTO_INTERVAL && fd < 0) { 1.48 + } else if ( 1.49 + listener->proto != MOONBR_PROTO_MAIN && 1.50 + listener->proto != MOONBR_PROTO_INTERVAL && 1.51 + fd < 0 1.52 + ) { 1.53 moonbr_child_log_fatal("Missing file descriptor from parent process"); 1.54 } 1.55 if (fd >= 0) moonbr_io_pushhandle(L, fd); 1.56 @@ -1000,6 +1014,7 @@ 1.57 MOONBR_DESTROY_IDLE_OR_ASSIGNED : 1.58 MOONBR_DESTROY_PREPARE 1.59 ); 1.60 + //if (worker->main) moonbr_initiate_shutdown(); // TODO 1.61 if (worker->prev_worker) worker->prev_worker->next_worker = worker->next_worker; 1.62 else worker->pool->first_worker = worker->next_worker; 1.63 if (worker->next_worker) worker->next_worker->prev_worker = worker->prev_worker; 1.64 @@ -1396,7 +1411,15 @@ 1.65 static void moonbr_connect(struct moonbr_pool *pool) { 1.66 struct moonbr_listener *listener = moonbr_pop_connected_listener(pool); 1.67 struct moonbr_worker *worker; 1.68 - if (listener->proto == MOONBR_PROTO_INTERVAL) { 1.69 + if (listener->proto == MOONBR_PROTO_MAIN) { 1.70 + worker = moonbr_pop_idle_worker(pool); 1.71 + if (moonbr_stat) { 1.72 + moonbr_log(LOG_INFO, "Dispatching main thread of pool #%i to PID %i", listener->pool->poolnum, (int)worker->pid); 1.73 + } 1.74 + worker->main = 1; 1.75 + moonbr_send_control_message(worker, MOONBR_COMMAND_CONNECT, -1, listener); 1.76 + /* do not push listener to queue of idle listeners */ 1.77 + } else if (listener->proto == MOONBR_PROTO_INTERVAL) { 1.78 worker = moonbr_pop_idle_worker(pool); 1.79 if (moonbr_stat) { 1.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); 1.81 @@ -1537,14 +1560,12 @@ 1.82 moonbr_remove_idle_listener(listener); 1.83 moonbr_add_connected_listener(listener); 1.84 } 1.85 - } else if (listener->proto == MOONBR_PROTO_INTERVAL) { 1.86 - if (!timercmp(&listener->type_specific.interval.wakeup, &now, >)) { 1.87 - moonbr_remove_idle_listener(listener); 1.88 - moonbr_add_connected_listener(listener); 1.89 - } 1.90 - } else { 1.91 - moonbr_log(LOG_CRIT, "Internal error (should not happen): Listener is neither an interval timer nor has the 'pollidx' value set"); 1.92 - moonbr_terminate_error(); 1.93 + } else if ( 1.94 + listener->proto != MOONBR_PROTO_INTERVAL || 1.95 + !timercmp(&listener->type_specific.interval.wakeup, &now, >) 1.96 + ) { 1.97 + moonbr_remove_idle_listener(listener); 1.98 + moonbr_add_connected_listener(listener); 1.99 } 1.100 } 1.101 /* process input from child processes */ 1.102 @@ -1856,6 +1877,7 @@ 1.103 struct moonbr_pool *pool; 1.104 const char *proto; 1.105 int i; 1.106 + int dynamic = 0; /* nonzero = listeners exist which require dynamic worker creation */ 1.107 pool = lua_touserdata(L, 1); 1.108 for (i=0; i<pool->listener_count; i++) { 1.109 struct moonbr_listener *listener = &pool->listener[i]; 1.110 @@ -1868,7 +1890,10 @@ 1.111 #endif 1.112 lua_getfield(L, 3, "proto"); 1.113 proto = lua_tostring(L, -1); 1.114 - if (proto && !strcmp(proto, "interval")) { 1.115 + if (proto && !strcmp(proto, "main")) { 1.116 + listener->proto = MOONBR_PROTO_MAIN; 1.117 + } else if (proto && !strcmp(proto, "interval")) { 1.118 + dynamic = 1; 1.119 listener->proto = MOONBR_PROTO_INTERVAL; 1.120 lua_getfield(L, 3, "name"); 1.121 { 1.122 @@ -1901,6 +1926,7 @@ 1.123 sizeof(listener->type_specific.socket.addr.addr_un) - 1.124 ((void *)listener->type_specific.socket.addr.addr_un.sun_path - (void *)&listener->type_specific.socket.addr.addr_un) 1.125 ) - 1; /* one byte for termination */ 1.126 + dynamic = 1; 1.127 listener->proto = MOONBR_PROTO_LOCAL; 1.128 lua_getfield(L, 3, "path"); 1.129 path = lua_tostring(L, -1); 1.130 @@ -1917,6 +1943,7 @@ 1.131 struct addrinfo *res, *addrinfo; 1.132 int errcode; 1.133 const char *ip; 1.134 + dynamic = 1; 1.135 lua_getfield(L, 3, "host"); 1.136 host = lua_isnil(L, -1) ? "::" : lua_tostring(L, -1); 1.137 if (!host) { 1.138 @@ -1995,23 +2022,29 @@ 1.139 } 1.140 } 1.141 lua_settop(L, 2); 1.142 - moonbr_listen_init_pool_forkoption("pre_fork", pre_fork, 1); 1.143 - moonbr_listen_init_pool_forkoption("min_fork", min_fork, pool->pre_fork > 2 ? pool->pre_fork : 2); 1.144 - moonbr_listen_init_pool_forkoption("max_fork", max_fork, pool->min_fork > 16 ? pool->min_fork : 16); 1.145 - if (!moonbr_listen_init_pool_timeoption("fork_delay", fork_delay, 0, 250000)) { 1.146 - luaL_error(L, "Option \"fork_delay\" is expected to be a non-negative number"); 1.147 - } 1.148 - if (!moonbr_listen_init_pool_timeoption("fork_error_delay", fork_error_delay, 2, 0)) { 1.149 - luaL_error(L, "Option \"fork_error_delay\" is expected to be a non-negative number"); 1.150 - } 1.151 - if (!moonbr_listen_init_pool_timeoption("exit_delay", exit_delay, 60, 0)) { 1.152 - luaL_error(L, "Option \"exit_delay\" is expected to be a non-negative number"); 1.153 - } 1.154 - if (timercmp(&pool->fork_error_delay, &pool->fork_delay, <)) { 1.155 - pool->fork_error_delay = pool->fork_delay; 1.156 - } 1.157 - if (!moonbr_listen_init_pool_timeoption("idle_timeout", idle_timeout, 0, 0)) { 1.158 - luaL_error(L, "Option \"idle_timeout\" is expected to be a non-negative number"); 1.159 + if (dynamic) { 1.160 + moonbr_listen_init_pool_forkoption("pre_fork", pre_fork, 1); 1.161 + moonbr_listen_init_pool_forkoption("min_fork", min_fork, pool->pre_fork > 2 ? pool->pre_fork : 2); 1.162 + moonbr_listen_init_pool_forkoption("max_fork", max_fork, pool->min_fork > 16 ? pool->min_fork : 16); 1.163 + if (!moonbr_listen_init_pool_timeoption("fork_delay", fork_delay, 0, 250000)) { 1.164 + luaL_error(L, "Option \"fork_delay\" is expected to be a non-negative number"); 1.165 + } 1.166 + if (!moonbr_listen_init_pool_timeoption("fork_error_delay", fork_error_delay, 2, 0)) { 1.167 + luaL_error(L, "Option \"fork_error_delay\" is expected to be a non-negative number"); 1.168 + } 1.169 + if (!moonbr_listen_init_pool_timeoption("exit_delay", exit_delay, 60, 0)) { 1.170 + luaL_error(L, "Option \"exit_delay\" is expected to be a non-negative number"); 1.171 + } 1.172 + if (timercmp(&pool->fork_error_delay, &pool->fork_delay, <)) { 1.173 + pool->fork_error_delay = pool->fork_delay; 1.174 + } 1.175 + if (!moonbr_listen_init_pool_timeoption("idle_timeout", idle_timeout, 0, 0)) { 1.176 + luaL_error(L, "Option \"idle_timeout\" is expected to be a non-negative number"); 1.177 + } 1.178 + } else { 1.179 + pool->pre_fork = 0; 1.180 + pool->min_fork = pool->listener_count; 1.181 + pool->max_fork = pool->listener_count; 1.182 } 1.183 lua_getfield(L, 2, "memory_limit"); 1.184 if (!lua_isnil(L, -1)) {