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)) {

Impressum / About Us