diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 0a12e8a..5f1143b 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -268,6 +268,8 @@ struct hcl_server_t hcl_server_worker_t* tail; } worker_list[2]; + int mux_pipe[2]; /* pipe to break the blocking multiplexer in the main server loop */ + pthread_mutex_t worker_mutex; pthread_mutex_t tmr_mutex; pthread_mutex_t log_mutex; @@ -893,11 +895,7 @@ static void vm_cleanup (hcl_t* hcl) static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode) { worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); - if (xtn->proto->worker->server->stopreq) hcl_abort(hcl); - - /* TODO: check how to this vm has been running. too long? abort it */ - /* check agains xtn->proto->worker->server->cfg.actor_max_runtime */ } /* @@ -906,7 +904,6 @@ static void gc_hcl (hcl_t* hcl) worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); } - static void fini_hcl (hcl_t* hcl) { worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); @@ -1064,7 +1061,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto) { /* error occurred inside the worker thread shouldn't affect the error information * in the server object. so here, i just log a message */ - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "sendmsg failure on %d - %hs\n", proto->worker->sck, strerror(errno)); + HCL_LOG2 (proto->hcl, SERVER_LOGMASK_ERROR, "sendmsg failure on %d - %hs\n", proto->worker->sck, strerror(errno)); return -1; } @@ -1263,7 +1260,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c) tmp = (hcl_ooch_t*)HCL_MMGR_REALLOC(proto->worker->server->mmgr, proto->tok.ptr, capa * HCL_SIZEOF(*tmp)); if (!tmp) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "out of memory in allocating a token buffer\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "out of memory in allocating a token buffer\n"); return -1; } @@ -1340,7 +1337,7 @@ static int get_token (hcl_server_proto_t* proto) GET_CHAR_TO(proto, c); if (!is_alphachar(c)) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "alphabetic character expected after a period\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "alphabetic character expected after a period\n"); return -1; } @@ -1357,7 +1354,7 @@ static int get_token (hcl_server_proto_t* proto) break; default: - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unrecognized character - [%jc]\n", c); + HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "unrecognized character - [%jc]\n", c); return -1; } return 0; @@ -1365,27 +1362,42 @@ static int get_token (hcl_server_proto_t* proto) static void exec_runtime_handler (hcl_tmr_t* tmr, const hcl_ntime_t* now, hcl_tmr_event_t* evt) { + /* [NOTE] this handler is executed in the main server thread + * when it calls hcl_tmr_fire() */ + hcl_server_proto_t* proto; proto = (hcl_server_proto_t*)evt->ctx; -//printf ("aborting hcl for runtime handler timeout...\n"); + + HCL_LOG0 (proto->worker->server->dummy_hcl, SERVER_LOGMASK_INFO, "Aborting script execution for max_actor_runtime exceeded\n"); /* TODO: include worker id into the message.. */ hcl_abort (proto->hcl); } static void exec_runtime_updater (hcl_tmr_t* tmr, hcl_tmr_index_t old_index, hcl_tmr_index_t new_index, hcl_tmr_event_t* evt) { + /* [NOTE] this handler is executed in the main server thread + * when it calls hcl_tmr_fire() */ + hcl_server_proto_t* proto; proto = (hcl_server_proto_t*)evt->ctx; HCL_ASSERT (proto->hcl, proto->exec_runtime_event_index == old_index); + + /* the event is being removed by hcl_tmr_fire() or by hcl_tmr_delete() + * if new_index is HCL_TMR_INVALID_INDEX. it's being updated if not. */ proto->exec_runtime_event_index = new_index; } static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmout) { + /* [NOTE] this is executed in the worker thread */ + hcl_tmr_event_t event; hcl_tmr_index_t index; + hcl_server_t* server; HCL_ASSERT (proto->hcl, proto->exec_runtime_event_index == HCL_TMR_INVALID_INDEX); + server = proto->worker->server; + HCL_MEMSET (&event, 0, HCL_SIZEOF(event)); event.ctx = proto; proto->hcl->vmprim.vm_gettime (proto->hcl, &event.when); @@ -1393,25 +1405,78 @@ static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmou event.handler = exec_runtime_handler; event.updater = exec_runtime_updater; - pthread_mutex_lock (&proto->worker->server->tmr_mutex); - index = hcl_tmr_insert(proto->worker->server->tmr, &event); - pthread_mutex_unlock (&proto->worker->server->tmr_mutex); - if (index == HCL_TMR_INVALID_INDEX) return -1; - + pthread_mutex_lock (&server->tmr_mutex); + index = hcl_tmr_insert(server->tmr, &event); proto->exec_runtime_event_index = index; - return 0; + if (index != HCL_TMR_INVALID_INDEX) + { + /* inform the server of timer event change */ + write (server->mux_pipe[1], "X", 1); /* don't care even if it fails */ + } + pthread_mutex_unlock (&server->tmr_mutex); + + return (index == HCL_TMR_INVALID_INDEX)? -1: 0; } static void delete_exec_timer (hcl_server_proto_t* proto) { + /* [NOTE] this is executed in the worker thread. if the event has been fired + * in the server thread, proto->exec_runtime_event_index should be + * HCL_TMR_INVALID_INDEX as set by exec_runtime_handler */ + hcl_server_t* server; + + server = proto->worker->server; + + pthread_mutex_lock (&server->tmr_mutex); if (proto->exec_runtime_event_index != HCL_TMR_INVALID_INDEX) { -//printf ("deleted exec timer..........\n"); - pthread_mutex_lock (&proto->worker->server->tmr_mutex); - hcl_tmr_delete (proto->worker->server->tmr, proto->exec_runtime_event_index); - pthread_mutex_unlock (&proto->worker->server->tmr_mutex); - proto->exec_runtime_event_index = HCL_TMR_INVALID_INDEX; + /* the event has not been fired yet. let's delete it + * if it has been fired, the index it shall be HCL_TMR_INVALID_INDEX already */ + + hcl_tmr_delete (server->tmr, proto->exec_runtime_event_index); + HCL_ASSERT (proto->hcl, proto->exec_runtime_event_index == HCL_TMR_INVALID_INDEX); + /*proto->exec_runtime_event_index = HCL_TMR_INVALID_INDEX; */ } + pthread_mutex_unlock (&server->tmr_mutex); +} + +static int execute_script (hcl_server_proto_t* proto, const hcl_bch_t* trigger) +{ + hcl_oop_t obj; + const hcl_ooch_t* failmsg = HCL_NULL; + hcl_server_t* server; + + server = proto->worker->server; + + hcl_server_proto_start_reply (proto); + if (server->cfg.actor_max_runtime.sec <= 0 && server->cfg.actor_max_runtime.sec <= 0) + { + obj = hcl_execute(proto->hcl); + if (!obj) failmsg = hcl_geterrmsg(proto->hcl); + } + else + { + if (insert_exec_timer(proto, &server->cfg.actor_max_runtime) <= -1) + { + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Cannot start execution timer\n"); + hcl_seterrbfmt (proto->hcl, HCL_ESYSMEM, "cannot start execution timer"); /* i do this just to compose the error message */ + failmsg = hcl_geterrmsg(proto->hcl); + } + else + { + obj = hcl_execute(proto->hcl); + if (!obj) failmsg = hcl_geterrmsg(proto->hcl); + delete_exec_timer (proto); + } + } + + if (hcl_server_proto_end_reply(proto, failmsg) <= -1) + { + HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "Cannot finalize reply for %hs\n", trigger); + return -1; + } + + return 0; } int hcl_server_proto_handle_request (hcl_server_proto_t* proto) @@ -1427,7 +1492,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) case HCL_SERVER_PROTO_TOKEN_EOF: if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unexpected EOF without .END\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unexpected EOF without .END\n"); return -1; } @@ -1437,21 +1502,21 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) case HCL_SERVER_PROTO_TOKEN_EXIT: if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".EXIT allowed in the top level only\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, ".EXIT allowed in the top level only\n"); return -1; } if (get_token(proto) <= -1) return -1; if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .EXIT\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No new line after .EXIT\n"); return -1; } hcl_server_proto_start_reply (proto); if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .EXIT\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .EXIT\n"); return -1; } return 0; @@ -1459,14 +1524,14 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) case HCL_SERVER_PROTO_TOKEN_BEGIN: if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".BEGIN not allowed to be nested\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, ".BEGIN not allowed to be nested\n"); return -1; } if (get_token(proto) <= -1) return -1; if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .BEGIN\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No new line after .BEGIN\n"); return -1; } @@ -1475,33 +1540,22 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) break; case HCL_SERVER_PROTO_TOKEN_END: - { - hcl_oop_t obj; - if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_BLOCK_LEVEL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".END without opening .BEGIN\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, ".END without opening .BEGIN\n"); return -1; } if (get_token(proto) <= -1) return -1; if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .BEGIN\n"); - return -1; - } - - hcl_server_proto_start_reply (proto); - obj = (hcl_getbclen(proto->hcl) > 0)? hcl_execute(proto->hcl): proto->hcl->_nil; - if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1) - { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .END\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No new line after .BEGIN\n"); return -1; } + if (execute_script(proto, ".END") <= -1) return -1; proto->req.state = HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL; break; - } case HCL_SERVER_PROTO_TOKEN_SCRIPT: { @@ -1512,63 +1566,28 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) obj = hcl_read(proto->hcl); if (!obj) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot read .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl)); + HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to read .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl)); return -1; } if (get_token(proto) <= -1) return -1; if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .SCRIPT contest\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No new line after .SCRIPT contest\n"); return -1; } if (hcl_compile(proto->hcl, obj) <= -1) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot compile .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl)); + HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to compile .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl)); return -1; } if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) { - const hcl_ooch_t* failmsg = HCL_NULL; - hcl_server_t* server; - - server = proto->worker->server; - - hcl_server_proto_start_reply (proto); - if (server->cfg.actor_max_runtime.sec <= 0 && server->cfg.actor_max_runtime.sec <= 0) - { - obj = hcl_execute(proto->hcl); - if (!obj) failmsg = hcl_geterrmsg(proto->hcl); - } - else - { - if (insert_exec_timer(proto, &server->cfg.actor_max_runtime) <= -1) - { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot start execution timer\n"); - /* use proto->hcl's error formatting instead of server's to avoid using mutex over the shared server->dummy_hcl */ - hcl_seterrbfmt (proto->hcl, HCL_ESYSMEM, "cannot start execution timer"); - failmsg = hcl_geterrmsg(proto->hcl); - } - else - { -//printf ("inserted exec timer..........\n"); - obj = hcl_execute(proto->hcl); - if (!obj) failmsg = hcl_geterrmsg(proto->hcl); - - delete_exec_timer (proto); - } - } - - if (hcl_server_proto_end_reply(proto, failmsg) <= -1) - { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .SCRIPT\n"); - return -1; - } + if (execute_script(proto, ".SCRIPT") <= -1) return -1; } break; - } case HCL_SERVER_PROTO_TOKEN_SHOW_WORKERS: @@ -1580,7 +1599,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .SHOW-WORKERS\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .SHOW-WORKERS\n"); return -1; } @@ -1595,13 +1614,13 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1) { - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .KILL-WORKER\n"); + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .KILL-WORKER\n"); return -1; } break; default: - hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unknown token - %d - %.*js\n", (int)proto->tok.type, proto->tok.len, proto->tok.ptr); + HCL_LOG3 (proto->hcl, SERVER_LOGMASK_ERROR, "Unknown token - %d - %.*js\n", (int)proto->tok.type, proto->tok.len, proto->tok.ptr); return -1; } @@ -1617,6 +1636,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p hcl_vmprim_t vmprim; hcl_tmr_t* tmr; dummy_hcl_xtn_t* xtn; + int pfd[2], fcv; server = (hcl_server_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*server) + xtnsize); if (!server) @@ -1646,8 +1666,30 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p { hcl_close (hcl); HCL_MMGR_FREE (mmgr, server); + return HCL_NULL; } + if (pipe(pfd) <= -1) + { + hcl_tmr_close (tmr); + hcl_close (hcl); + HCL_MMGR_FREE (mmgr, server); + return HCL_NULL; + } + +#if defined(O_CLOEXEC) + fcv = fcntl(pfd[0], F_GETFD, 0); + if (fcv >= 0) fcntl(pfd[0], F_SETFD, fcv | O_CLOEXEC); + fcv = fcntl(pfd[1], F_GETFD, 0); + if (fcv >= 0) fcntl(pfd[1], F_SETFD, fcv | O_CLOEXEC); +#endif +#if defined(O_NONBLOCK) + fcv = fcntl(pfd[0], F_GETFL, 0); + if (fcv >= 0) fcntl(pfd[0], F_SETFL, fcv | O_NONBLOCK); + fcv = fcntl(pfd[1], F_GETFL, 0); + if (fcv >= 0) fcntl(pfd[1], F_SETFL, fcv | O_NONBLOCK); +#endif + xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl); xtn->server = server; @@ -1665,6 +1707,9 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p HCL_INITNTIME (&server->cfg.worker_idle_timeout, 0, 0); HCL_INITNTIME (&server->cfg.actor_max_runtime, 0, 0); + server->mux_pipe[0] = pfd[0]; + server->mux_pipe[1] = pfd[1]; + pthread_mutex_init (&server->worker_mutex, HCL_NULL); pthread_mutex_init (&server->tmr_mutex, HCL_NULL); pthread_mutex_init (&server->log_mutex, HCL_NULL); @@ -1678,6 +1723,8 @@ void hcl_server_close (hcl_server_t* server) pthread_mutex_destroy (&server->tmr_mutex); pthread_mutex_destroy (&server->worker_mutex); + close (server->mux_pipe[0]); + close (server->mux_pipe[1]); hcl_tmr_close (server->tmr); hcl_close (server->dummy_hcl); HCL_MMGR_FREE (server->mmgr, server); @@ -1702,11 +1749,11 @@ static void close_worker_socket (hcl_server_worker_t* worker) { if (worker->proto) { - hcl_logbfmt (worker->proto->hcl, SERVER_LOGMASK_INFO, "closing worker socket %d\n", worker->sck); + HCL_LOG1 (worker->proto->hcl, SERVER_LOGMASK_INFO, "Closing worker socket %d\n", worker->sck); } else { - hcl_server_logbfmt (worker->server, SERVER_LOGMASK_INFO, "closing worker socket %d\n", worker->sck); + HCL_LOG1 (worker->server->dummy_hcl, SERVER_LOGMASK_INFO, "Closing worker socket %d\n", worker->sck); } close (worker->sck); worker->sck = -1; @@ -1948,19 +1995,24 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) pthread_t thr; hcl_ntime_t tmout; hcl_server_worker_t* worker; - struct pollfd pfd[1]; - int n; + struct pollfd pfd[2]; + int n, pc; purge_all_workers (server, HCL_SERVER_WORKER_STATE_DEAD); pthread_mutex_lock (&server->tmr_mutex); n = hcl_tmr_gettmout(server->tmr, HCL_NULL, &tmout); pthread_mutex_unlock (&server->tmr_mutex); - if (n <= -1) HCL_INITNTIME (&tmout, 1, 0); + if (n <= -1) HCL_INITNTIME (&tmout, 10, 0); - pfd[0].fd = srv_fd; - pfd[0].events = POLLIN | POLLERR; - n = poll(pfd, 1, HCL_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec)); +/* TODO: swtich to faster multiplexer like epoll or kqueue */ + pc = 0; + pfd[pc].fd = server->mux_pipe[0]; + pfd[pc++].events = POLLIN | POLLERR; + pfd[pc].fd = srv_fd; + pfd[pc++].events = POLLIN | POLLERR; + + n = poll(pfd, pc, HCL_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec)); if (n <= -1) { if (server->stopreq) break; /* normal termination requested */ @@ -1975,11 +2027,16 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) hcl_tmr_fire (server->tmr, HCL_NULL, HCL_NULL); pthread_mutex_unlock (&server->tmr_mutex); - while (n > 0) + for (n = 0; n < pc; n++) { - --n; + if (!pfd[n].revents /*& (POLLIN | POLLHUP | POLLERR) */) continue; - if (pfd[n].revents /*& (POLLIN | POLLHUP | POLLERR) */) + if (pfd[n].fd == server->mux_pipe[0]) + { + char tmp[128]; + while (read(server->mux_pipe[0], tmp, HCL_SIZEOF(tmp)) > 0) /* nothing */; + } + else if (pfd[n].fd == srv_fd) { cli_len = HCL_SIZEOF(cli_addr); cli_fd = accept(pfd[n].fd, (struct sockaddr*)&cli_addr, &cli_len); @@ -1993,7 +2050,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) break; } - hcl_server_logbfmt (server, SERVER_LOGMASK_INFO, "accepted worker - socket %d\n", cli_fd); + HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_INFO, "Accepted worker - socket %d\n", cli_fd); worker = alloc_worker(server, cli_fd); if (pthread_create(&thr, &thr_attr, worker_main, worker) != 0) @@ -2008,12 +2065,15 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) purge_all_workers (server, HCL_SERVER_WORKER_STATE_DEAD); pthread_attr_destroy (&thr_attr); + + close (srv_fd); return xret; } void hcl_server_stop (hcl_server_t* server) { server->stopreq = 1; + write (server->mux_pipe[1], "Q", 1); /* don't care about failure */ } int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const void* value) diff --git a/lib/main2.c b/lib/main2.c index 03a7133..c30aade 100644 --- a/lib/main2.c +++ b/lib/main2.c @@ -402,16 +402,20 @@ static int handle_dbgopt (hcl_server_t* server, const char* str) /* ========================================================================= */ -#define MIN_MEMSIZE 512000ul +#define MIN_WORKER_STACK_SIZE 512000ul +#define MIN_ACTOR_HEAP_SIZE 512000ul int main (int argc, char* argv[]) { hcl_bci_t c; static hcl_bopt_lng_t lopt[] = { - { ":log", 'l' }, - { ":memsize", 'm' }, - { "large-pages", '\0' }, + { ":log", 'l' }, + { "large-pages", '\0' }, + { ":worker-stack-size", '\0' }, + { ":worker-idle-timeout",'\0' }, + { ":actor-heap-size", 'm' }, + { ":actor-max-runtime", '\0' }, #if defined(HCL_BUILD_DEBUG) { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ #endif @@ -430,8 +434,10 @@ int main (int argc, char* argv[]) const char* logopt = HCL_NULL; const char* dbgopt = HCL_NULL; - hcl_oow_t memsize = MIN_MEMSIZE; - hcl_ntime_t tmout = { 0, 0 }; + hcl_oow_t worker_stack_size = MIN_ACTOR_HEAP_SIZE; + hcl_ntime_t worker_idle_timeout = { 0, 0 }; + hcl_oow_t actor_heap_size = MIN_ACTOR_HEAP_SIZE; + hcl_ntime_t actor_max_runtime = { 0, 0 }; int large_pages = 0; unsigned int trait; @@ -453,8 +459,8 @@ int main (int argc, char* argv[]) break; case 'm': - memsize = strtoul(opt.arg, HCL_NULL, 0); - if (memsize <= MIN_MEMSIZE) memsize = MIN_MEMSIZE; + actor_heap_size = strtoul(opt.arg, HCL_NULL, 0); + if (actor_heap_size <= MIN_ACTOR_HEAP_SIZE) actor_heap_size = MIN_ACTOR_HEAP_SIZE; break; case '\0': @@ -463,6 +469,21 @@ int main (int argc, char* argv[]) large_pages = 1; break; } + else if (hcl_compbcstr(opt.lngopt, "worker-stack-size") == 0) + { + worker_stack_size = strtoul(opt.arg, HCL_NULL, 0); + if (worker_stack_size <= MIN_WORKER_STACK_SIZE) actor_heap_size = MIN_WORKER_STACK_SIZE; + } + else if (hcl_compbcstr(opt.lngopt, "worker-idle-timeout") == 0) + { + worker_idle_timeout.sec = strtoul(opt.arg, HCL_NULL, 0); + break; + } + else if (hcl_compbcstr(opt.lngopt, "actor-max-runtime") == 0) + { + actor_max_runtime.sec = strtoul(opt.arg, HCL_NULL, 0); + break; + } #if defined(HCL_BUILD_DEBUG) else if (hcl_compbcstr(opt.lngopt, "debug") == 0) { @@ -521,11 +542,10 @@ int main (int argc, char* argv[]) else trait &= ~HCL_SERVER_TRAIT_USE_LARGE_PAGES; hcl_server_setoption (server, HCL_SERVER_TRAIT, &trait); - /*hcl_server_setoption (server, HCL_SERVER_WORKER_STACK_SIZE, ???);*/ - hcl_server_setoption (server, HCL_SERVER_ACTOR_HEAP_SIZE, &memsize); - - HCL_INITNTIME (&tmout, 5, 0); - hcl_server_setoption (server, HCL_SERVER_ACTOR_MAX_RUNTIME, &tmout); + hcl_server_setoption (server, HCL_SERVER_WORKER_STACK_SIZE, &worker_stack_size); + hcl_server_setoption (server, HCL_SERVER_WORKER_IDLE_TIMEOUT, &worker_idle_timeout); + hcl_server_setoption (server, HCL_SERVER_ACTOR_HEAP_SIZE, &actor_heap_size); + hcl_server_setoption (server, HCL_SERVER_ACTOR_MAX_RUNTIME, &actor_max_runtime); g_server = server; set_signal (SIGINT, handle_sigint);