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

Impressum / About Us