# HG changeset patch # User jbe # Date 1429032766 -7200 # Node ID ebaac38b722435164e3f4b8b75764f1de93baf84 # Parent 37532927dba9d0de7bc1c70c9c4e6d0eff753fc8 Moved functions in source code to avoid necessity of forward declaration diff -r 37532927dba9 -r ebaac38b7224 moonbridge.c --- a/moonbridge.c Tue Apr 14 19:30:53 2015 +0200 +++ b/moonbridge.c Tue Apr 14 19:32:46 2015 +0200 @@ -943,135 +943,6 @@ } -/*** Functions to handle previously created 'struct moonbr_worker' structures ***/ - -#define moonbr_try_destroy_worker_stat(str, field) \ - moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: " str " %li", worker->pool->poolnum, (int)worker->pid, (long)childusage.field); - -/* Destroys a worker structure if socket connections have been closed and child process has terminated */ -static int moonbr_try_destroy_worker(struct moonbr_worker *worker) { - if (worker->controlfd != -1 || worker->errorfd != -1) return MOONBR_DESTROY_NONE; - { - int childstatus; - struct rusage childusage; - { - pid_t waitedpid; - while ( - (waitedpid = wait4(worker->pid, &childstatus, WNOHANG, &childusage)) == -1 - ) { - if (errno != EINTR) { - moonbr_log(LOG_CRIT, "Error in wait4() call: %s", strerror(errno)); - moonbr_terminate_error(); - } - } - if (!waitedpid) return 0; /* return 0 if worker couldn't be destroyed */ - if (waitedpid != worker->pid) { - moonbr_log(LOG_CRIT, "Wrong PID returned by wait4() call"); - moonbr_terminate_error(); - } - } - if (WIFEXITED(childstatus)) { - if (WEXITSTATUS(childstatus) || moonbr_stat) { - moonbr_log( - WEXITSTATUS(childstatus) ? LOG_WARNING : LOG_INFO, - "Child process in pool #%i with PID %i returned with exit code %i", worker->pool->poolnum, (int)worker->pid, WEXITSTATUS(childstatus) - ); - } - } else if (WIFSIGNALED(childstatus)) { - if (WCOREDUMP(childstatus)) { - moonbr_log(LOG_ERR, "Child process in pool #%i with PID %i died from signal %i (core dump was created)", worker->pool->poolnum, (int)worker->pid, WTERMSIG(childstatus)); - } else if (WTERMSIG(childstatus) == SIGALRM) { - moonbr_log(LOG_WARNING, "Child process in pool #%i with PID %i exited prematurely due to timeout", worker->pool->poolnum, (int)worker->pid); - } else { - moonbr_log(LOG_ERR, "Child process in pool #%i with PID %i died from signal %i", worker->pool->poolnum, (int)worker->pid, WTERMSIG(childstatus)); - } - } else { - moonbr_log(LOG_CRIT, "Illegal exit status from child process in pool #%i with PID %i", worker->pool->poolnum, (int)worker->pid); - moonbr_terminate_error(); - } - if (moonbr_stat) { - moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: user time %s", worker->pool->poolnum, (int)worker->pid, moonbr_format_timeval(&childusage.ru_utime)); - moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: system time %s", worker->pool->poolnum, (int)worker->pid, moonbr_format_timeval(&childusage.ru_stime)); - moonbr_try_destroy_worker_stat("max resident set size", ru_maxrss); - moonbr_try_destroy_worker_stat("integral shared memory size", ru_ixrss); - moonbr_try_destroy_worker_stat("integral unshared data", ru_idrss); - moonbr_try_destroy_worker_stat("integral unshared stack", ru_isrss); - moonbr_try_destroy_worker_stat("page replaims", ru_minflt); - moonbr_try_destroy_worker_stat("page faults", ru_majflt); - moonbr_try_destroy_worker_stat("swaps", ru_nswap); - moonbr_try_destroy_worker_stat("block input operations", ru_inblock); - moonbr_try_destroy_worker_stat("block output operations", ru_oublock); - moonbr_try_destroy_worker_stat("messages sent", ru_msgsnd); - moonbr_try_destroy_worker_stat("messages received", ru_msgrcv); - moonbr_try_destroy_worker_stat("signals received", ru_nsignals); - moonbr_try_destroy_worker_stat("voluntary context switches", ru_nvcsw); - moonbr_try_destroy_worker_stat("involuntary context switches", ru_nivcsw); - } - } - { - int retval = ( - (worker->idle || worker->assigned) ? - MOONBR_DESTROY_IDLE_OR_ASSIGNED : - MOONBR_DESTROY_PREPARE - ); - //if (worker->main) moonbr_initiate_shutdown(); // TODO - if (worker->prev_worker) worker->prev_worker->next_worker = worker->next_worker; - else worker->pool->first_worker = worker->next_worker; - if (worker->next_worker) worker->next_worker->prev_worker = worker->prev_worker; - else worker->pool->last_worker = worker->prev_worker; - if (worker->idle) { - if (worker->prev_idle_worker) worker->prev_idle_worker->next_idle_worker = worker->next_idle_worker; - else worker->pool->first_idle_worker = worker->next_idle_worker; - if (worker->next_idle_worker) worker->next_idle_worker->prev_idle_worker = worker->prev_idle_worker; - else worker->pool->last_idle_worker = worker->prev_idle_worker; - worker->pool->idle_worker_count--; - } - if (!worker->assigned) worker->pool->unassigned_worker_count--; - worker->pool->total_worker_count--; - worker->pool->worker_count_stat = 1; - if (worker->errorlinebuf) free(worker->errorlinebuf); - free(worker); - return retval; - } -} - -/* Marks a worker as idle and stores it in a queue, optionally setting 'idle_expiration' value */ -static void moonbr_add_idle_worker(struct moonbr_worker *worker) { - worker->prev_idle_worker = worker->pool->last_idle_worker; - if (worker->prev_idle_worker) worker->prev_idle_worker->next_idle_worker = worker; - else worker->pool->first_idle_worker = worker; - worker->pool->last_idle_worker = worker; - worker->idle = 1; - worker->pool->idle_worker_count++; - if (worker->assigned) { - worker->assigned = 0; - worker->pool->unassigned_worker_count++; - } - worker->pool->worker_count_stat = 1; - if (timerisset(&worker->pool->idle_timeout)) { - struct timeval now; - moonbr_now(&now); - timeradd(&now, &worker->pool->idle_timeout, &worker->idle_expiration); - } -} - -/* Pops a worker from the queue of idle workers (idle queue must not be empty) */ -static struct moonbr_worker *moonbr_pop_idle_worker(struct moonbr_pool *pool) { - struct moonbr_worker *worker; - worker = pool->first_idle_worker; - pool->first_idle_worker = worker->next_idle_worker; - if (pool->first_idle_worker) pool->first_idle_worker->prev_idle_worker = NULL; - else pool->last_idle_worker = NULL; - worker->next_idle_worker = NULL; - worker->idle = 0; - worker->pool->idle_worker_count--; - worker->assigned = 1; - worker->pool->unassigned_worker_count--; - worker->pool->worker_count_stat = 1; - return worker; -} - - /*** Functions for queues of 'struct moonbr_listener' ***/ /* Appends a 'struct moonbr_listener' to the queue of idle listeners and registers it for poll() */ @@ -1277,6 +1148,135 @@ } +/*** Functions to handle previously created 'struct moonbr_worker' structures ***/ + +#define moonbr_try_destroy_worker_stat(str, field) \ + moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: " str " %li", worker->pool->poolnum, (int)worker->pid, (long)childusage.field); + +/* Destroys a worker structure if socket connections have been closed and child process has terminated */ +static int moonbr_try_destroy_worker(struct moonbr_worker *worker) { + if (worker->controlfd != -1 || worker->errorfd != -1) return MOONBR_DESTROY_NONE; + { + int childstatus; + struct rusage childusage; + { + pid_t waitedpid; + while ( + (waitedpid = wait4(worker->pid, &childstatus, WNOHANG, &childusage)) == -1 + ) { + if (errno != EINTR) { + moonbr_log(LOG_CRIT, "Error in wait4() call: %s", strerror(errno)); + moonbr_terminate_error(); + } + } + if (!waitedpid) return 0; /* return 0 if worker couldn't be destroyed */ + if (waitedpid != worker->pid) { + moonbr_log(LOG_CRIT, "Wrong PID returned by wait4() call"); + moonbr_terminate_error(); + } + } + if (WIFEXITED(childstatus)) { + if (WEXITSTATUS(childstatus) || moonbr_stat) { + moonbr_log( + WEXITSTATUS(childstatus) ? LOG_WARNING : LOG_INFO, + "Child process in pool #%i with PID %i returned with exit code %i", worker->pool->poolnum, (int)worker->pid, WEXITSTATUS(childstatus) + ); + } + } else if (WIFSIGNALED(childstatus)) { + if (WCOREDUMP(childstatus)) { + moonbr_log(LOG_ERR, "Child process in pool #%i with PID %i died from signal %i (core dump was created)", worker->pool->poolnum, (int)worker->pid, WTERMSIG(childstatus)); + } else if (WTERMSIG(childstatus) == SIGALRM) { + moonbr_log(LOG_WARNING, "Child process in pool #%i with PID %i exited prematurely due to timeout", worker->pool->poolnum, (int)worker->pid); + } else { + moonbr_log(LOG_ERR, "Child process in pool #%i with PID %i died from signal %i", worker->pool->poolnum, (int)worker->pid, WTERMSIG(childstatus)); + } + } else { + moonbr_log(LOG_CRIT, "Illegal exit status from child process in pool #%i with PID %i", worker->pool->poolnum, (int)worker->pid); + moonbr_terminate_error(); + } + if (moonbr_stat) { + moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: user time %s", worker->pool->poolnum, (int)worker->pid, moonbr_format_timeval(&childusage.ru_utime)); + moonbr_log(LOG_INFO, "Resource usage in pool #%i for PID %i: system time %s", worker->pool->poolnum, (int)worker->pid, moonbr_format_timeval(&childusage.ru_stime)); + moonbr_try_destroy_worker_stat("max resident set size", ru_maxrss); + moonbr_try_destroy_worker_stat("integral shared memory size", ru_ixrss); + moonbr_try_destroy_worker_stat("integral unshared data", ru_idrss); + moonbr_try_destroy_worker_stat("integral unshared stack", ru_isrss); + moonbr_try_destroy_worker_stat("page replaims", ru_minflt); + moonbr_try_destroy_worker_stat("page faults", ru_majflt); + moonbr_try_destroy_worker_stat("swaps", ru_nswap); + moonbr_try_destroy_worker_stat("block input operations", ru_inblock); + moonbr_try_destroy_worker_stat("block output operations", ru_oublock); + moonbr_try_destroy_worker_stat("messages sent", ru_msgsnd); + moonbr_try_destroy_worker_stat("messages received", ru_msgrcv); + moonbr_try_destroy_worker_stat("signals received", ru_nsignals); + moonbr_try_destroy_worker_stat("voluntary context switches", ru_nvcsw); + moonbr_try_destroy_worker_stat("involuntary context switches", ru_nivcsw); + } + } + { + int retval = ( + (worker->idle || worker->assigned) ? + MOONBR_DESTROY_IDLE_OR_ASSIGNED : + MOONBR_DESTROY_PREPARE + ); + if (worker->main) moonbr_initiate_shutdown(); + if (worker->prev_worker) worker->prev_worker->next_worker = worker->next_worker; + else worker->pool->first_worker = worker->next_worker; + if (worker->next_worker) worker->next_worker->prev_worker = worker->prev_worker; + else worker->pool->last_worker = worker->prev_worker; + if (worker->idle) { + if (worker->prev_idle_worker) worker->prev_idle_worker->next_idle_worker = worker->next_idle_worker; + else worker->pool->first_idle_worker = worker->next_idle_worker; + if (worker->next_idle_worker) worker->next_idle_worker->prev_idle_worker = worker->prev_idle_worker; + else worker->pool->last_idle_worker = worker->prev_idle_worker; + worker->pool->idle_worker_count--; + } + if (!worker->assigned) worker->pool->unassigned_worker_count--; + worker->pool->total_worker_count--; + worker->pool->worker_count_stat = 1; + if (worker->errorlinebuf) free(worker->errorlinebuf); + free(worker); + return retval; + } +} + +/* Marks a worker as idle and stores it in a queue, optionally setting 'idle_expiration' value */ +static void moonbr_add_idle_worker(struct moonbr_worker *worker) { + worker->prev_idle_worker = worker->pool->last_idle_worker; + if (worker->prev_idle_worker) worker->prev_idle_worker->next_idle_worker = worker; + else worker->pool->first_idle_worker = worker; + worker->pool->last_idle_worker = worker; + worker->idle = 1; + worker->pool->idle_worker_count++; + if (worker->assigned) { + worker->assigned = 0; + worker->pool->unassigned_worker_count++; + } + worker->pool->worker_count_stat = 1; + if (timerisset(&worker->pool->idle_timeout)) { + struct timeval now; + moonbr_now(&now); + timeradd(&now, &worker->pool->idle_timeout, &worker->idle_expiration); + } +} + +/* Pops a worker from the queue of idle workers (idle queue must not be empty) */ +static struct moonbr_worker *moonbr_pop_idle_worker(struct moonbr_pool *pool) { + struct moonbr_worker *worker; + worker = pool->first_idle_worker; + pool->first_idle_worker = worker->next_idle_worker; + if (pool->first_idle_worker) pool->first_idle_worker->prev_idle_worker = NULL; + else pool->last_idle_worker = NULL; + worker->next_idle_worker = NULL; + worker->idle = 0; + worker->pool->idle_worker_count--; + worker->assigned = 1; + worker->pool->unassigned_worker_count--; + worker->pool->worker_count_stat = 1; + return worker; +} + + /*** Functions to communicate with child processes ***/ /* Tells child process to terminate */