Beispiel #1
0
static int sb_get_idle_worker()
{
  int i, j, res;
  worker_score *ws_record;
  process_score *ps_record;
  int idle = 0;

#ifdef __APACHE24__
  ap_generation_t ap_my_generation;
  ap_mpm_query(AP_MPMQ_GENERATION, &ap_my_generation);
#endif

  ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &mruby_thread_limit);
  ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mruby_server_limit);

  if (!ap_extended_status)
    return idle;

  for (i = 0; i < mruby_server_limit; ++i) {
    ps_record = ap_get_scoreboard_process(i);
    for (j = 0; j < mruby_thread_limit; ++j) {
      ws_record = ap_get_scoreboard_worker(i, j);
      res = ws_record->status;
      if (!ps_record->quiescing && ps_record->pid) {
        if (res == SERVER_READY && ps_record->generation == ap_my_generation)
          idle++;
      }
    }
  }

  return idle;
}
Beispiel #2
0
static global_snapshot *get_global_stats(apr_pool_t *p, request_rec *r)
{
	global_snapshot *global_snap = apr_pcalloc(p, sizeof(global_snapshot));
	init_global_snap(global_snap);
	int i;
	for (i = 0; i < global_stats->count; i++) {
		// Selecting slots with present or past processes
		if (ap_get_scoreboard_process(i)->pid) {
			update_global_snap(global_snap, &global_stats->stats[i], r);
		}
	}
	finish_global_snap(global_snap); // Calculates averages
	return global_snap;
}
Beispiel #3
0
static apr_off_t sb_get_kbcount()
{
    int i, j, res;
    unsigned long lres;
    apr_off_t bytes;
    apr_off_t bcount, kbcount;
    worker_score *ws_record;
    process_score *ps_record;

    ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &mruby_thread_limit);
    ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mruby_server_limit);

    bcount = 0;
    kbcount = 0;

   if (!ap_extended_status)
        return kbcount;

    for (i = 0; i < mruby_server_limit; ++i) {
        ps_record = ap_get_scoreboard_process(i);
        for (j = 0; j < mruby_thread_limit; ++j) {

            ws_record = ap_get_scoreboard_worker(i, j);

            res = ws_record->status;

            lres = ws_record->access_count;
            bytes = ws_record->bytes_served;

            if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) {
                bcount += bytes;

                if (bcount >= KBYTE) {
                    kbcount += (bcount >> 10);
                    bcount = bcount & 0x3ff;
                }
            }
        }
Beispiel #4
0
AP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback)
{
    int i;
    extra_process_t *cur_extra;
    int max_daemons;

    ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);

    /* now see who is done */
    for (i = 0; i < max_daemons; ++i) {
        process_score *ps = ap_get_scoreboard_process(i);
        pid_t pid = ps->pid;

        if (pid == 0) {
            continue; /* not every scoreboard entry is in use */
        }

        if (reclaim_one_pid(pid, DO_NOTHING)) {
            mpm_callback(i, 0, 0);
        }
    }

    cur_extra = extras;
    while (cur_extra) {
        ap_generation_t old_gen;
        extra_process_t *next = cur_extra->next;

        if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
            if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
                mpm_callback(-1, cur_extra->pid, old_gen);
            }
            else {
                AP_DEBUG_ASSERT(1 == 0);
            }
        }
        cur_extra = next;
    }
}
Beispiel #5
0
static PyObject *wsgi_server_metrics(void)
{
    PyObject *scoreboard_dict = NULL;

    PyObject *process_list = NULL;

    PyObject *object = NULL;

    apr_time_t current_time;
    apr_interval_time_t running_time;

    global_score *gs_record;
    worker_score *ws_record;
    process_score *ps_record;

    int j, i;

    if (!wsgi_interns_initialized)
        wsgi_initialize_interned_strings();

    /* Scoreboard needs to exist and server metrics enabled. */

    if (!ap_exists_scoreboard_image()) {
        Py_INCREF(Py_None);

        return Py_None;
    }

    if (!wsgi_daemon_pool) {
        if (!wsgi_server_config->server_metrics) {
            Py_INCREF(Py_None);

            return Py_None;
        }
    }
#if defined(MOD_WSGI_WITH_DAEMONS)
    else {
        if (!wsgi_daemon_process->group->server_metrics) {
            Py_INCREF(Py_None);

            return Py_None;
        }
    }
#endif

    gs_record = ap_get_scoreboard_global();

    if (!gs_record) {
        Py_INCREF(Py_None);

        return Py_None;
    }

    /* Return everything in a dictionary. Start with global. */

    scoreboard_dict = PyDict_New();

    object = wsgi_PyInt_FromLong(gs_record->server_limit);
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(server_limit), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLong(gs_record->thread_limit);
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(thread_limit), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLong(gs_record->running_generation);
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(running_generation), object);
    Py_DECREF(object);

    object = PyFloat_FromDouble(apr_time_sec((
            double)gs_record->restart_time));
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(restart_time), object);
    Py_DECREF(object);

    current_time = apr_time_now();

    object = PyFloat_FromDouble(apr_time_sec((double)current_time));
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(current_time), object);
    Py_DECREF(object);

    running_time = (apr_uint32_t)apr_time_sec((double)
            current_time - ap_scoreboard_image->global->restart_time);

    object = wsgi_PyInt_FromLongLong(running_time);
    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(running_time), object);
    Py_DECREF(object);

    /* Now add in the processes/workers. */

    process_list = PyList_New(0);

    for (i = 0; i < gs_record->server_limit; ++i) {
        PyObject *process_dict = NULL;
        PyObject *worker_list = NULL;

        ps_record = ap_get_scoreboard_process(i);

        process_dict = PyDict_New();
        PyList_Append(process_list, process_dict);

        object = wsgi_PyInt_FromLong(i);
        PyDict_SetItem(process_dict,
                WSGI_INTERNED_STRING(process_num), object);
        Py_DECREF(object);

        object = wsgi_PyInt_FromLong(ps_record->pid);
        PyDict_SetItem(process_dict,
                WSGI_INTERNED_STRING(pid), object);
        Py_DECREF(object);

        object = wsgi_PyInt_FromLong(ps_record->generation);
        PyDict_SetItem(process_dict,
                WSGI_INTERNED_STRING(generation), object);
        Py_DECREF(object);

        object = PyBool_FromLong(ps_record->quiescing);
        PyDict_SetItem(process_dict,
                WSGI_INTERNED_STRING(quiescing), object);
        Py_DECREF(object);

        worker_list = PyList_New(0);
        PyDict_SetItem(process_dict,
                WSGI_INTERNED_STRING(workers), worker_list);

        for (j = 0; j < gs_record->thread_limit; ++j) {
            PyObject *worker_dict = NULL;

#if AP_MODULE_MAGIC_AT_LEAST(20071023,0)
            ws_record = ap_get_scoreboard_worker_from_indexes(i, j);
#else
            ws_record = ap_get_scoreboard_worker(i, j);
#endif

            worker_dict = PyDict_New();

            PyList_Append(worker_list, worker_dict);

            object = wsgi_PyInt_FromLong(ws_record->thread_num);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(thread_num), object);
            Py_DECREF(object);

            object = wsgi_PyInt_FromLong(ws_record->generation);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(generation), object);
            Py_DECREF(object);

            object = wsgi_status_flags[ws_record->status];
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(status), object);

            object = wsgi_PyInt_FromLong(ws_record->access_count);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(access_count), object);
            Py_DECREF(object);

            object = wsgi_PyInt_FromUnsignedLongLong(ws_record->bytes_served);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(bytes_served), object);
            Py_DECREF(object);

            object = PyFloat_FromDouble(apr_time_sec(
                    (double)ws_record->start_time));
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(start_time), object);
            Py_DECREF(object);

            object = PyFloat_FromDouble(apr_time_sec(
                    (double)ws_record->stop_time));
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(stop_time), object);
            Py_DECREF(object);

            object = PyFloat_FromDouble(apr_time_sec(
                    (double)ws_record->last_used));
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(last_used), object);
            Py_DECREF(object);

            object = wsgi_PyString_FromString(ws_record->client);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(client), object);
            Py_DECREF(object);

            object = wsgi_PyString_FromString(ws_record->request);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(request), object);
            Py_DECREF(object);

            object = wsgi_PyString_FromString(ws_record->vhost);
            PyDict_SetItem(worker_dict,
                    WSGI_INTERNED_STRING(vhost), object);
            Py_DECREF(object);

            Py_DECREF(worker_dict);
        }

        Py_DECREF(worker_list);
        Py_DECREF(process_dict);
    }

    PyDict_SetItem(scoreboard_dict,
            WSGI_INTERNED_STRING(processes), process_list);
    Py_DECREF(process_list);

    return scoreboard_dict;
}
Beispiel #6
0
AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
                                            ap_reclaim_callback_fn_t *mpm_callback)
{
    apr_time_t waittime = 1024 * 16;
    int i;
    extra_process_t *cur_extra;
    int not_dead_yet;
    int max_daemons;
    apr_time_t starttime = apr_time_now();
    /* this table of actions and elapsed times tells what action is taken
     * at which elapsed time from starting the reclaim
     */
    struct {
        action_t action;
        apr_time_t action_time;
    } action_table[] = {
        {DO_NOTHING, 0}, /* dummy entry for iterations where we reap
                          * children but take no action against
                          * stragglers
                          */
        {SEND_SIGTERM, apr_time_from_sec(3)},
        {SEND_SIGTERM, apr_time_from_sec(5)},
        {SEND_SIGTERM, apr_time_from_sec(7)},
        {SEND_SIGKILL, apr_time_from_sec(9)},
        {GIVEUP,       apr_time_from_sec(10)}
    };
    int cur_action;      /* index of action we decided to take this
                          * iteration
                          */
    int next_action = 1; /* index of first real action */

    ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);

    do {
        apr_sleep(waittime);
        /* don't let waittime get longer than 1 second; otherwise, we don't
         * react quickly to the last child exiting, and taking action can
         * be delayed
         */
        waittime = waittime * 4;
        if (waittime > apr_time_from_sec(1)) {
            waittime = apr_time_from_sec(1);
        }

        /* see what action to take, if any */
        if (action_table[next_action].action_time <= apr_time_now() - starttime) {
            cur_action = next_action;
            ++next_action;
        }
        else {
            cur_action = 0; /* nothing to do */
        }

        /* now see who is done */
        not_dead_yet = 0;
        for (i = 0; i < max_daemons; ++i) {
            process_score *ps = ap_get_scoreboard_process(i);
            pid_t pid = ps->pid;

            if (pid == 0) {
                continue; /* not every scoreboard entry is in use */
            }

            if (reclaim_one_pid(pid, action_table[cur_action].action)) {
                mpm_callback(i, 0, 0);
            }
            else {
                ++not_dead_yet;
            }
        }

        cur_extra = extras;
        while (cur_extra) {
            ap_generation_t old_gen;
            extra_process_t *next = cur_extra->next;

            if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
                if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
                    mpm_callback(-1, cur_extra->pid, old_gen);
                }
                else {
                    AP_DEBUG_ASSERT(1 == 0);
                }
            }
            else {
                ++not_dead_yet;
            }
            cur_extra = next;
        }
#if APR_HAS_OTHER_CHILD
        apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART);
#endif

    } while (not_dead_yet > 0 &&
             action_table[cur_action].action != GIVEUP);
}