Apache-Scoreboard

 view release on metacpan or  search on metacpan

Scoreboard.xs  view on Meta::CPAN

{
      HV *stash;
      int server_limit, thread_limit;

      /* SERVER_LIMIT and THREAD_LIMIT constants are deprecated, use
       * $image->server_limit and $image->thread_limit instead */
#ifndef DUMMY_SCOREBOARD
    ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
    ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
#else
    /* XXX: how can we figure out that data w/o having an access to
     * ap_mpm_query? */
    server_limit = 0;
    thread_limit = 0;
#endif
    
    stash = gv_stashpv("Apache::Const", TRUE);
    newCONSTSUB(stash, "SERVER_LIMIT", newSViv(server_limit));
    
    stash = gv_stashpv("Apache::Const", TRUE);
    newCONSTSUB(stash, "THREAD_LIMIT", newSViv(thread_limit));

    stash = gv_stashpv("Apache::Scoreboard", TRUE);
    newCONSTSUB(stash, "REMOTE_SCOREBOARD_TYPE",
                newSVpv(REMOTE_SCOREBOARD_TYPE, 0));

}

MP_INLINE
static worker_score *my_get_scoreboard_worker(pTHX_
                                              modperl_scoreboard_t *image,
                                              int x, int y)
{
    if (((x < 0) || (image->server_limit < x)) ||
        ((y < 0) || (image->thread_limit < y))) {
        Perl_croak(aTHX_ "worker score [%d][%d] is out of limit", x, y);
    }
    return &image->sb->servers[x][y];
}

MP_INLINE
static process_score *my_get_scoreboard_process(pTHX_
                                                modperl_scoreboard_t *image,
                                                int x)
{
    if ((x < 0) || (image->server_limit < x)) {
        Perl_croak(aTHX_ "parent score [%d] is out of limit", x);
    }
    return &image->sb->parent[x];
}

static void image_sanity_check(pTHX)
{
#ifdef DUMMY_SCOREBOARD
    Perl_croak(aTHX_ "Don't call the image() method when not"
               "running under mod_perl");
#endif
}

#ifdef DUMMY_SCOREBOARD
#define MY_WARN fprintf(stderr,
#else
#define MY_WARN ap_log_error(APLOG_MARK, APLOG_ERR, 0, modperl_global_get_server_rec(),
#endif
      
#if 0
static void debug_dump_sb(modperl_scoreboard_t *image)
{
    int i, j;

    for (i = 0; i < image->server_limit; i++) {
        for (j = 0; j < image->thread_limit; j++) {
            worker_score *ws = &image->sb->servers[i][j];
            if (ws->access_count) {
                MY_WARN
                    "rcv %02d-%02d: stat: %c cnt: %d\n", i, j,
                    status_flags[ws->status],
                    (int)ws->access_count);
            }
        }
    }
}
#endif







MODULE = Apache::Scoreboard   PACKAGE = Apache::Scoreboard   PREFIX = scoreboard_

BOOT:
{

    /* XXX: this must be performed only once and before other threads are spawned.
     * but not sure. could be that need to use local storage.
     *
     */
    status_flags_init();
    
    constants_init(aTHX);
}

int
scoreboard_send(r)
    Apache2::RequestRec r


SV *
freeze(image)
    Apache::Scoreboard image

    PREINIT:
    int psize, ssize, tsize, msize, i;
    char buf[SIZE16*4];
    char *dptr, *ptr = buf;
    scoreboard *sb;

    CODE:
    sb = image->sb;
    
    psize = sizeof(process_score) * image->server_limit;
    msize = sizeof(worker_score)  * image->thread_limit;
    ssize = msize * image->server_limit;
    tsize = psize + ssize + sizeof(global_score) + sizeof(buf);
    /* fprintf(stderr, "sizes %d, %d, %d, %d, %d\n",
       psize, ssize, sizeof(global_score) , sizeof(buf), tsize); */
                 
    pack16(ptr, psize);
    ptr += SIZE16;
    pack16(ptr, ssize);
    ptr += SIZE16;
    pack16(ptr, image->server_limit);
    ptr += SIZE16;
    pack16(ptr, image->thread_limit);

    RETVAL = NEWSV(0, tsize);
    dptr = SvPVX(RETVAL);
    SvCUR_set(RETVAL, tsize+1);
    SvPOK_only(RETVAL);

    /* fill the data buffer with the data we want to freeze */
    Move(&buf[0],        dptr, sizeof(buf),          char);
    dptr += sizeof(buf);
    Move(&sb->parent[0], dptr, psize,                char);
    dptr += psize;
    for (i = 0; i < image->server_limit; i++) {
        Move(sb->servers[i], dptr, msize, char);
        dptr += msize;
    }
    Move(&sb->global,    dptr, sizeof(global_score), char);

    OUTPUT:
    RETVAL

Apache::Scoreboard
thaw(CLASS, pool, packet)
    SV *CLASS
    APR::Pool pool
    SV *packet

    PREINIT:
    modperl_scoreboard_t *image;
    scoreboard *sb;
    int psize, ssize;
    char *ptr;
    int i;
    
    CODE:
    if (!(SvOK(packet) && SvCUR(packet) > (SIZE16*2))) {
        XSRETURN_UNDEF;
    }

    CLASS = CLASS; /* avoid warnings */
 
    image = (modperl_scoreboard_t *)apr_pcalloc(pool, sizeof(*image));

    ptr = SvPVX(packet);
    psize = unpack16(ptr);
    ptr += SIZE16;
    ssize = unpack16(ptr);
    ptr += SIZE16;
    image->server_limit = unpack16(ptr);
    ptr += SIZE16;
    image->thread_limit = unpack16(ptr);
    ptr += SIZE16;

Scoreboard.xs  view on Meta::CPAN

Apache::ScoreboardParentScore
parent_score(image, idx=0)
    Apache::Scoreboard image
    int idx

    PREINIT:
    process_score *ps;
    
    CODE:
    ps = my_get_scoreboard_process(aTHX_ image, idx);
    /* XXX */
    if (!ps->quiescing && ps->pid) {
        RETVAL = (modperl_parent_score_t *)apr_pcalloc(image->pool,
                                                       (sizeof(*RETVAL)));
        RETVAL->record = ps;
        RETVAL->idx    = idx;
        RETVAL->image  = image;
    }
    else {
        XSRETURN_UNDEF;
    }

    OUTPUT:
    RETVAL

Apache::ScoreboardWorkerScore
worker_score(image, parent_idx, worker_idx)
    Apache::Scoreboard image
    int parent_idx
    int worker_idx

    PREINIT:
    worker_score *ws;
    
    CODE:
    ws = my_get_scoreboard_worker(aTHX_ image, parent_idx, worker_idx);
    RETVAL = (modperl_worker_score_t *)apr_pcalloc(image->pool,
                                                   (sizeof(*RETVAL)));
    RETVAL->parent_idx = parent_idx;
    RETVAL->worker_idx = worker_idx;
    RETVAL->record = ws;
    
    OUTPUT:
    RETVAL

SV *
pids(image)
    Apache::Scoreboard image

    PREINIT:
    AV *av = newAV();
    int i;
    scoreboard *sb;

    CODE:
    sb = image->sb;
    for (i = 0; i < image->server_limit; i++) {
        if (!(sb->parent[i].pid)) {
            break;
        }
        /* fprintf(stderr, "pids: server %d: pid %d\n",
           i, (int)(sb->parent[i].pid)); */
        av_push(av, newSViv(sb->parent[i].pid));
    }
        
    RETVAL = newRV_noinc((SV*)av);

    OUTPUT:
    RETVAL

# XXX: need to move pid_t => apr_proc_t and work with pid->pid as in
# find_child_by_pid from scoreboard.c

int
parent_idx_by_pid(image, pid)   
    Apache::Scoreboard image
    pid_t pid

    PREINIT:
    int i;
    scoreboard *sb;

    CODE:
    sb = image->sb;
    RETVAL = -1;

    for (i = 0; i < image->server_limit; i++) {
        if (sb->parent[i].pid == pid) {
            RETVAL = i;
            break;
        }
    }

    OUTPUT:
    RETVAL

SV *
thread_numbers(image, parent_idx)
    Apache::Scoreboard image
    int parent_idx

    PREINIT:
    AV *av = newAV();
    int i;
    scoreboard *sb;

    CODE:
    sb = image->sb;

    for (i = 0; i < image->thread_limit; ++i) {
        /* fprintf(stderr, "thread_num: server %d, thread %d pid %d\n",
           i, sb->servers[parent_idx][i].thread_num,
           (int)(sb->parent[parent_idx].pid)); */
        
        av_push(av, newSViv(sb->servers[parent_idx][i].thread_num));
    }

    RETVAL = newRV_noinc((SV*)av);

    OUTPUT:
    RETVAL

apr_uint32_t
scoreboard_up_time(image)
    Apache::Scoreboard image








MODULE = Apache::Scoreboard PACKAGE = Apache::ScoreboardParentScore PREFIX = parent_score_
    
Apache::ScoreboardParentScore
next(self)
    Apache::ScoreboardParentScore self

    PREINIT:
    int next_idx;
    process_score *ps;
    modperl_scoreboard_t *image;

    CODE:
    image = self->image;
    next_idx = self->idx + 1;
    if (next_idx <= image->server_limit) {
        ps = my_get_scoreboard_process(aTHX_ image, next_idx);
    }
    else {
        XSRETURN_UNDEF;
    }

    if (ps->pid) {
        RETVAL = (modperl_parent_score_t *)apr_pcalloc(image->pool,
                                                       sizeof(*RETVAL));
        RETVAL->record = ps;
        RETVAL->idx    = next_idx;
        RETVAL->image  = image;
    }
    else {
        XSRETURN_UNDEF;
    }

    OUTPUT:
    RETVAL

Apache::ScoreboardWorkerScore
worker_score(self)
    Apache::ScoreboardParentScore self



( run in 2.647 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )