ApacheBench

 view release on metacpan or  search on metacpan

TODO  view on Meta::CPAN

* implement per-run execute() using system threads, then global execute() can
  just fire off as many threads as there are runs
  - this would allow (re-)sending of individual runs, iterations within a run
  - complications with concurrent request slots: does each thread keep
    its own set of file descriptors, or (sh)(c)ould threads share them?
* need a way to simulate real-world problems: for example
  - slow dialup modem connections
    o e.g. add an automatic delay after each request in a run
    o also support a pre-configured delay inside a run
  - user-presses-stop, aka broken socket
* bring up-to-date with current Apache 2.0 distribution of ab.c
  - including SSL support
* perl subroutine hooks between requests in a sequence, with access
  to all prior regression data and ability to dynamically change current or
  future requests in sequence

doc/README.old  view on Meta::CPAN


	After having your desired configuration and runs added, call 
	$re->execute to perform the requests,


RETURN VALUE

	Bench returns a hash reference which has the key  for each run,
	(keys as "run0", "run1", etc), besides "warn" and "total_time"
	and "bytes_received". Each run is again a hash, which has the
	keys for each url,besides "thread".

	The  value  stored  in  the  key  for each run is again a hash
	reference which has the following key/value pairs:

		"hostname" => a string of the url's hostname;
		"software" => a string of the server software;
		"path" 	   => a string of the url's path;
		"port"	   => the port of the server;
		"doc_length" => the document length(amount of body read);
		"completed_requests" => the requests completed;

doc/README.old  view on Meta::CPAN

			connect in total among our requests to this url;
		"average_connect_time" => the average time taken to 
			connect this server  for all the requests;
		"average_time" => the average time taken to process and
			connect this server for all the requests;

	if "POST" is used:

		"total_posted" => total amount posted to the server;

	The value stored in the key "threads" is an array reference which
	keeps  information  for each sequence of requests (that is, visit
	each of the urls once in order).
	Each entry of the array  is  a  reference to a hash which has the
	following key/value pairs:

		"total_time" => an array reference, keeps how much time 
				taken (process	and connect) for each url 
				in order for this thread;
		"connect_time" => an array reference,keeps how much time
				taken to connect each server  in  order 
				for this thread;
		"page_content" => an array  reference, keeps the contents 
				read from the servers;
		"headers"	=> an array reference keeping the headers
				for every urls in the thread.

	The value stored  in the key  "warn"  is a string containing the
	warn and error message generated by ab.	

	The value stored in the key "total_time" is the total time taken
	for all our processs and connections in total.	

	The value stored in the key "bytes_received" is the total bytes
	received from all the requests in total.

doc/README.upgrading_0.5x-0.6x  view on Meta::CPAN

     $rhash = $re->{'regression'};

4) The regression hash no longer contains any per-URL information.
   Half of the data keyed on URL was wrong, and the other half was
   fairly useless, so it is no longer returned at all.

   The fix:
   - remove all references to URLs in the regression hash, e.g.
     anything that looks like $re->{'run0'}->{'http://test.url/'}

5) What was stored in the 'threads' array reference (for each run),
   is now in the top-level of the regression hash for each run.
   The term threads was confusing, especially considering an upcoming
   rewrite will probably include multi-threaded request sending.

   The fix:
   - replace all $re->{'run0'}->{'threads'} with $rhash->{'run0'}

   Notice that each runI entry in the regression hash is now an ARRAY ref, not
   a HASH ref.  Your Perl script will fail unless you treat them as such.

6) Read the documentation.  There is a much more intuitive way of
   getting regression data using object method calls, rather than poking
   around through the huge regression hash.  Configuration can also now be
   done with method calls.

--

src/ApacheBench.xs  view on Meta::CPAN


    if (AB_DEBUG_XS) printf("AB_DEBUG: done with test()\n");

    RETVAL = newHV();/* ready to get information stored in global variables */

    for (k = 0; k < registry->number_of_runs; k++) {
        if (registry->memory[k] >= 1) {
            AV *started = newAV();/* number of started requests for each url */
            AV *good = newAV();   /* number of good responses for each url */
            AV *failed = newAV(); /* number of bad responses for each url */
            tmpav = newAV();      /* array to keep the thread information */

            if (AB_DEBUG_XS) printf("AB_DEBUG: getting regression info for run %d\n", k);

            for (i = 0; i < registry->repeats[k]; i++) {
                AV *th_t = newAV();  /* times for processing and connecting */
                AV *th_r = newAV();  /* times for http request */
                AV *th_c = newAV();  /* connecting times */
                AV *page_contents = newAV(); /* pages read from servers */
                AV *request_headers = newAV(); /* HTTP requests sent to servers */
                AV *request_body = newAV(); /* HTTP requests sent to servers */

src/apachebench/execute.c  view on Meta::CPAN

    int i,j;

#ifdef AB_DEBUG
    printf("AB_DEBUG: start of initialize()\n");
#endif

    registry->cookie = malloc(registry->number_of_runs * sizeof(char *));
    registry->buffersize = malloc(registry->number_of_runs * sizeof(int));
    registry->auto_cookies = (char ***) calloc(registry->number_of_runs, sizeof(char **)); // must be zeroed for the calloc code in http_util.c

    registry->which_thread = malloc(registry->number_of_urls * sizeof(int *));
    registry->arranged = malloc(registry->number_of_urls * sizeof(int));

    for (i = 0; i < registry->number_of_urls; i++)
        registry->arranged[i] = 0;
    for (i = 0; i < registry->number_of_runs; i++) {
        for (j = registry->position[i]; j < registry->position[i+1]; j++)
            registry->which_thread[j] = malloc(registry->repeats[i] * sizeof(int));
        for (j = 0; j < registry->repeats[i]; j++)
            registry->which_thread[registry->position[i]][j] = j;
        registry->need_to_be_done += registry->repeats[i] * (registry->position[i+1] - registry->position[i]);
    }
    registry->ready_to_run_queue = malloc(registry->need_to_be_done * sizeof(struct threadval));
    for (i = 0; i < registry->number_of_runs; i++) {
        if (registry->order[i] == DEPTH_FIRST) {
            if ((registry->priority == EQUAL_OPPORTUNITY) || (registry->tail < registry->concurrency)) {
                registry->arranged[registry->position[i]] = 1;
                registry->ready_to_run_queue[registry->tail].run = i;
                registry->ready_to_run_queue[registry->tail].url = registry->position[i];
                registry->ready_to_run_queue[registry->tail++].thread = 0;
            }
        } else for (j = 0; j < registry->repeats[i]; j++)
            if ((registry->priority == EQUAL_OPPORTUNITY) || (registry->tail < registry->concurrency)) {
                registry->arranged[registry->position[i]] += 1;
                registry->ready_to_run_queue[registry->tail].run = i;
                registry->ready_to_run_queue[registry->tail].thread = j;
                registry->ready_to_run_queue[registry->tail++].url = registry->position[i];
            }
    }
    registry->hostname = malloc(registry->number_of_urls * sizeof(char *));
    registry->path = malloc(registry->number_of_urls * sizeof(char *));
    registry->port = malloc(registry->number_of_urls * sizeof(int));
    registry->ctypes = malloc(registry->number_of_urls * sizeof(char *));
    registry->req_headers = malloc(registry->number_of_urls * sizeof(char *));
    registry->keepalive = malloc(registry->number_of_urls * sizeof(bool));
    registry->url_tlimit = malloc(registry->number_of_urls * sizeof(double));

src/apachebench/execute.c  view on Meta::CPAN

    memset(registry->con, 0, registry->concurrency * sizeof(struct connection));

#ifdef AB_DEBUG
    printf("AB_DEBUG: start of test()\n");
#endif

    for (i = 0; i < registry->concurrency; i++) {
        registry->con[i].url = registry->ready_to_run_queue[i].url;
        registry->con[i].run = registry->ready_to_run_queue[i].run;
        registry->con[i].state = STATE_READY;
        registry->con[i].thread = registry->ready_to_run_queue[i].thread;
    }

#ifdef AB_DEBUG
    printf("AB_DEBUG: test() - stage 1\n");
#endif

    registry->stats = calloc(registry->number_of_urls, sizeof(struct data *));
    for (i = 0; i < registry->number_of_runs; i++) {
        int j;
        for (j = registry->position[i]; j < registry->position[i+1]; j++)

src/apachebench/execute.c  view on Meta::CPAN

#ifdef AB_DEBUG
                printf("AB_DEBUG: test() - stage 5.5.4, Time taken for current request = %d ms; Per-url time limit = %.4f sec; for run %d, url %d\n", timedif(url_now, c->start_time), registry->url_tlimit[c->url], c->run, c->url - registry->position[c...
                printf("AB_DEBUG: test() - stage 5.5.5, registry->done = %d, i = %d\n", registry->done, i);
#endif
                if (registry->url_tlimit[c->url] &&
                    timedif(url_now, c->start_time) > (registry->url_tlimit[c->url] * 1000)) {
                    char *warn = malloc(256 * sizeof(char));
#ifdef AB_DEBUG
                    printf("AB_DEBUG: test() - stage 5.5.5.3, registry->done = %d, i = %d\n", registry->done, i);
#endif
                    sprintf(warn, "Per-url time limit reached (%.3f sec) for run %d, url %d, iteration %d; connection closed prematurely", registry->url_tlimit[c->url], c->run, c->url - registry->position[c->run], c->thread);
                    myerr(registry->warn_and_error, warn);
                    free(warn);

                    registry->failed[c->url]++;
                    close_connection(registry, c);
                    continue;
                }
            }

            if (registry->con[i].state == STATE_DONE)

src/apachebench/http_util.c  view on Meta::CPAN

}


/* --------------------------------------------------------- */

/* extract cookies from response_data (Set-Cookie: headers) and save to auto_cookies */

static void
allocate_auto_cookie_memory(struct global * registry, struct connection * c) {
#ifdef AB_DEBUG
    printf("AB_DEBUG: start of allocate_auto_cookie_memory(): run %d, thread %d\n", c->run, c->thread);
#endif

    if (registry->auto_cookies[c->run] == NULL) {
        registry->auto_cookies[c->run] = (char **) calloc(registry->repeats[c->run], sizeof(char *));
#ifdef AB_DEBUG
        printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 1: run %d, thread %d\n", c->run, c->thread);
#endif
    }
        
    if (registry->auto_cookies[c->run][c->thread] == NULL) {
        registry->auto_cookies[c->run][c->thread] = (char *) calloc(CBUFFSIZE, sizeof(char));
#ifdef AB_DEBUG
        printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 2: run %d, thread %d\n", c->run, c->thread);
#endif
    }
}

static void
extract_cookies_from_response(struct global * registry, struct connection * c) {
    char * set_cookie_hdr, * eoh;

#ifdef AB_DEBUG
    printf("AB_DEBUG: start of extract_cookies_from_response()\n");
#endif
    if (registry->failed[c->url] > 0)
        return;

    allocate_auto_cookie_memory(registry, c);

#ifdef AB_DEBUG
    printf("AB_DEBUG: extract_cookies_from_response() - stage 1; run %d, thread %d\n", c->run, c->thread);
#endif

    if (! c->response_headers) return;

    set_cookie_hdr = strstr(c->response_headers, "\r\nSet-Cookie: ");
    while (set_cookie_hdr) {
        remove_existing_cookie_from_auto_cookies(registry, c, set_cookie_hdr);

#ifdef AB_DEBUG
        printf("AB_DEBUG: extract_cookies_from_response() - stage 2.1; run %d, thread %d, postdata[%d] = %s\n", c->run, c->thread, c->url, registry->postdata[c->url]);
#endif

        eoh = strstr(set_cookie_hdr+2, "\r\n");
        if (! strnstr(set_cookie_hdr, "=; Expires=", eoh - set_cookie_hdr)) // hack: do not set expired headers
            // drop the "Set-" from beginning to just append "Cookie: ....\r\n"
            strncat(registry->auto_cookies[c->run][c->thread], set_cookie_hdr + 6, eoh - set_cookie_hdr - 4);

#ifdef AB_DEBUG
        printf("AB_DEBUG: extract_cookies_from_response() - stage 2.2; run %d, thread %d, auto_cookies[%d][%d] = %s\n", c->run, c->thread, c->run, c->url, registry->auto_cookies[c->run][c->thread]);
#endif

        set_cookie_hdr = strstr(set_cookie_hdr+1, "\r\nSet-Cookie: ");
    }
}

/* remove existing cookies from registry->auto_cookies[..][..] which will be set again by extract_cookies_from_response() */

static void
remove_existing_cookie_from_auto_cookies(struct global * registry, struct connection * c, char * set_cookie_hdr) {

src/apachebench/http_util.c  view on Meta::CPAN

    // first need to find the name of cookie on current "Set-Cookie: " header line
    cookie_name = (char *) calloc(CBUFFSIZE, sizeof(char));
    strcat(cookie_name, "Cookie: ");
    eoh = strstr(set_cookie_hdr+14, "\r\n");
    strncat(cookie_name, set_cookie_hdr+14, strnstr(set_cookie_hdr+14, "=", eoh-(set_cookie_hdr+14)) - (set_cookie_hdr+14));

#ifdef AB_DEBUG
    printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1\n");
#endif

    existing_cookie = strstr(registry->auto_cookies[c->run][c->thread], cookie_name);

#ifdef AB_DEBUG
    printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1.1\n");
#endif
    if (existing_cookie) {
        new_auto_cookies = (char *) calloc(CBUFFSIZE, sizeof(char));

#ifdef AB_DEBUG
        printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.1\n");
#endif

        strncpy(new_auto_cookies, registry->auto_cookies[c->run][c->thread], existing_cookie - registry->auto_cookies[c->run][c->thread]);
        end_of_existing_cookie = strstr(existing_cookie, "\r\n");
        strcat(new_auto_cookies, end_of_existing_cookie+2);

#ifdef AB_DEBUG
        printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.2\n");
#endif

        // overwrite auto_cookies with new version with existing_cookie removed
        strcpy(registry->auto_cookies[c->run][c->thread], new_auto_cookies);
        free(new_auto_cookies);

#ifdef AB_DEBUG
        printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.3, auto_cookies[%d][%d] = %s\n", c->url, c->thread, registry->auto_cookies[c->url][c->thread]);
#endif
    }
#ifdef AB_DEBUG
    printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 3, cookie_name = %s\n", cookie_name);
#endif

    free(cookie_name);

#ifdef AB_DEBUG
    printf("AB_DEBUG: end of remove_existing_cookie_from_auto_cookies(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);

src/apachebench/regression_data.c  view on Meta::CPAN

#include <stdlib.h>
#include <string.h>

#include "types.h"
#include "regression_data.h"


static void
initialize_regression_data(struct data * s) {
    s->run = 0;
    s->thread = 0;
    s->read = 0;
    s->bread = 0;
    s->ctime = 0;
    s->rtime = 0;
    s->time = 0;

    s->request = 0;
    s->request_headers = 0;

    s->response_headers = 0;

src/apachebench/regression_data.c  view on Meta::CPAN

#ifdef AB_DEBUG
    printf("AB_DEBUG: start of store_regression_data(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);
#endif

    if (registry->failed[c->url] > 0)
        return;

    if (c->read >= registry->buffersize[c->run] &&
	registry->memory[c->run] >= 3) {
        char * warn = malloc(256 * sizeof(char));
        sprintf(warn, "[run %d, iter %d, req %d]: Buffer size of %d is too small, got response of size %d", c->run, c->thread, c->url, registry->buffersize[c->run], c->read);
        myerr(registry->warn_and_error, warn);
        free(warn);
    }

    if (c->read == 0) {
        if (registry->memory[c->run] >= 3)
            c->response = "";
        if (registry->memory[c->run] >= 2)
            c->response_headers = "";
    }

src/apachebench/regression_data.c  view on Meta::CPAN

        int postdata_generation_time = timedif(c->connect_time, c->before_postdata_time);
        if (c->connect_time.tv_sec || c->connect_time.tv_usec)
            s.ctime = timedif(c->connect_time, c->start_time) - postdata_generation_time;
        else
            s.ctime = 0;
        if (c->sent_request_time.tv_sec || c->sent_request_time.tv_usec)
            s.rtime = timedif(c->sent_request_time, c->start_time) - postdata_generation_time;
        else
            s.rtime = 0;
        s.time = timedif(c->done_time, c->start_time) - postdata_generation_time;
        s.thread = c->thread;
        s.read = c->read;
    }

#ifdef AB_DEBUG
    printf("AB_DEBUG: store_regression_data() - stage 2\n");
#endif

    if (registry->memory[c->run] >= 2) {
        s.bread = c->bread;
        s.request_headers = malloc((strlen(c->request_headers)+1) * sizeof(char));

src/apachebench/regression_data.c  view on Meta::CPAN

#endif

            strcat(s.request, registry->postdata[c->url]);
        } else {
            s.request = malloc((strlen(c->request)+1) * sizeof(char));
            strcpy(s.request, c->request);
        }
    }

#ifdef AB_DEBUG
    printf("AB_DEBUG: store_regression_data() - saving stats, c->url %d, c->thread %d\n", c->url, c->thread);
#endif

    registry->stats[c->url][c->thread] = s;

    registry->total_bytes_received += c->read;
}

src/apachebench/socket_io.c  view on Meta::CPAN

    char *post_body;

#ifdef AB_DEBUG
    printf("AB_DEBUG: write_request() - stage 1, registry->done = %d\n", registry->done);
#endif
    gettimeofday(&c->before_postdata_time, 0);

    /* the url in this run has dynamicly-generated postdata */
    if (registry->posting[c->url] == 2) {
        res = call_perl_function__one_arg(registry->postsubs[c->url],
                                          newSVpv(c->url > 0 ? registry->stats[c->url - 1][c->thread].response : "", 0));

        if (SvPOK(res)) {
            post_body = SvPV(res, len);
#ifdef AB_DEBUG
            printf("AB_DEBUG: write_request() - stage 1-postsub.2, postsub res %s, length %d\n", post_body, (int)len);
#endif
            registry->postdata[c->url] = post_body;
            registry->postlen[c->url] = (int) len;
        } else {
            registry->postdata[c->url] = "";

src/apachebench/socket_io.c  view on Meta::CPAN


    if (registry->keepalive[i])
        strcat(c->request_headers, "Connection: Keep-Alive\r\n");
    if (registry->cookie[c->run]) {
        strcat(c->request_headers, "Cookie: ");
        strcat(c->request_headers, registry->cookie[c->run]);
        strcat(c->request_headers, "\r\n");
    }

#ifdef AB_DEBUG
    printf("AB_DEBUG: reset_request() - stage 2.1: c->run %d; c->thread %d\n", c->run, c->thread);
#endif

    allocate_auto_cookie_memory(registry, c);

    if (registry->use_auto_cookies[c->run] && registry->auto_cookies[c->run] != NULL && registry->auto_cookies[c->run][c->thread] != NULL) {

#ifdef AB_DEBUG
        printf("AB_DEBUG: reset_request() - stage 2.2a: request_headers %s\n", c->request_headers);
        printf("AB_DEBUG: reset_request() - stage 2.2b: auto_cookies %s\n", registry->auto_cookies[c->run][c->thread]);
#endif

        strcat(c->request_headers, registry->auto_cookies[c->run][c->thread]);
    }

#ifdef AB_DEBUG
    printf("AB_DEBUG: reset_request() - stage 2.3: c->run %d; c->thread %d\n", c->run, c->thread);
#endif

    if (registry->req_headers[i]) {
        strcat(c->request_headers, registry->req_headers[i]);
        strcat(c->request_headers, "\r\n");
    }

    strcat(c->request_headers, "\r\n");

#ifdef AB_DEBUG
    printf("AB_DEBUG: reset_request() - stage 2.4: c->run %d; c->thread %d\n", c->run, c->thread);
#endif

    strcpy(c->request, c->request_headers);
    c->reqlen = strlen(c->request);

#ifdef AB_DEBUG
    printf("AB_DEBUG: reset_request() - stage 3\n");
#endif

#ifdef CHARSET_EBCDIC

src/apachebench/socket_io.c  view on Meta::CPAN

#endif                                /* CHARSET_EBCDIC */

    return 0;
}

/* --------------------------------------------------------- */

/* setup the next request in the sequence / repetition / run to be sent
   returns 1 if the next request is ready to be sent,
   returns 0 if this connection is done,
   sets the connection values: c->run, c->url, c->thread, and c->state,
   as well as helper structures: registry->which_thread[][],
     registry->ready_to_run_queue[], and registry->arranged[]
*/

static int
schedule_next_request(struct global * registry, struct connection * c) {

    if (registry->priority == RUN_PRIORITY) {
        /* if the last url in this run has repeated enough, go to next run */
        if (registry->started[registry->position[c->run + 1] - 1] >= registry->repeats[c->run])
            return schedule_request_in_next_run(registry, c);

        /* possible more resources needed in this group */
        /* started[position[c->run + 1] - 1] < repeats[c->run] */
        if (registry->order[c->run] == DEPTH_FIRST) {
            /* for depth_first, connect the next one and restart the
               sequence if we're at the last url in the run */
            if (++c->url == registry->position[c->run + 1]) {
                c->url = registry->position[c->run];
                c->thread = registry->started[c->url];
            }
            return 1;
        } else { /* breadth_first */
            if (c->url < (registry->position[c->run + 1] - 1))
                /* TODO: check if (registry->finished[c->url] > 0) ??? */
                registry->which_thread[c->url+1][registry->finished[c->url] - 1] = c->thread;
            if (registry->started[c->url] == registry->repeats[c->run])
                /* go to next url in sequence if we repeated this one enough */
                c->url++;
            if (c->url == registry->position[c->run]) {
                /* this is the first url in the sequence: set its repetition
                   number to the initial incremental value (0, 1, 2, 3, ...) */
                c->thread = registry->which_thread[c->url][registry->started[c->url]];
                return 1;
            }
            /* only start another request from this run if more requests of the
               previous url in the sequence have finished(in-order execution)*/
            if (registry->started[c->url] < registry->finished[c->url - 1]) {
                c->thread = registry->started[c->url];
                return 1;
            } else {
                return schedule_request_in_next_run(registry, c);
            }
        }

    } else { /* equal_opportunity */
        /* we use a FIFO to queue up requests to be sent */
        if (c->url < registry->position[c->run + 1]-1) {
            /* if url is before the end of the url sequence,
               add it to the tail of the request queue */
            registry->ready_to_run_queue[registry->tail].url = c->url + 1;
            registry->ready_to_run_queue[registry->tail].thread = c->thread;
            registry->ready_to_run_queue[registry->tail++].run = c->run;
            registry->arranged[c->url + 1]++;
        } else if (registry->order[c->run] == DEPTH_FIRST
                   && registry->arranged[registry->position[c->run]] < registry->repeats[c->run]) {
            /* end of the url sequence in depth_first with more repetitions
               necessary: start from the beginning of the url sequence */
            registry->ready_to_run_queue[registry->tail].url = registry->position[c->run];
            registry->ready_to_run_queue[registry->tail].thread = registry->arranged[registry->position[c->run]]++;
            registry->ready_to_run_queue[registry->tail++].run = c->run;
        }

        if (registry->head >= registry->tail) {
            c->state = STATE_DONE;
            return 0;
        }
        c->thread = registry->ready_to_run_queue[registry->head].thread;
        c->url = registry->ready_to_run_queue[registry->head].url;
        c->run = registry->ready_to_run_queue[registry->head++].run;
        return 1;
    }
}

/* --------------------------------------------------------- */

/* move connection to the next run, because the current run either doesn't need
   or cannot use any more connection slots (resources)

src/apachebench/socket_io.c  view on Meta::CPAN

               or is a depth_first run which only requires one slot,
               so doesn't need this resource anymore */
            c->run++;
            continue;
        }
        /* start at first url in the run */
        c->url = registry->position[c->run];
        if (registry->started[c->url] < registry->repeats[c->run]) {
            /* for breadth_first, start one more connect to 1st url if possible
               for depth_first, get started here */
            c->thread = registry->which_thread[c->url][registry->started[c->url]];
            return 1;
        }
        /* look at each url in the sequence until we find one which needs
           to be repeated more */
        while (++c->url < registry->position[c->run + 1]
               && registry->started[c->url] >= registry->repeats[c->run]);
        /* only start another request from this run if more requests of the
           previous url in the sequence have finished (in-order execution) */
        if (registry->started[c->url] < registry->finished[c->url - 1]) {
            c->thread = registry->which_thread[c->url][registry->started[c->url]];
            return 1;
        } else
            /* this run doesn't need any more resources */
            c->run++;
    }
    /* no one needs any more resources */
    c->state = STATE_DONE;
    return 0;
}

src/apachebench/types.h  view on Meta::CPAN

    int state;
    int url;			/* which url are we testing */
    int read;			/* amount of bytes read */
    int bread;			/* amount of body read */
    int length;			/* Content-Length value used for keep-alive */
    char cbuff[CBUFFSIZE];	/* a buffer to store server response header */
    int cbx;			/* offset in cbuffer */
    int keepalive;		/* non-zero if a keep-alive request */
    int gotheader;		/* non-zero if we have the entire header in
				 * cbuff */
    int thread;			/* Thread number */
    int run;

    struct timeval start_time, connect_time, before_postdata_time, sent_request_time, done_time;

    char *request;		/* HTTP request */
    char *request_headers;
    int reqlen;

    char *response_headers;	/* HTTP response */
    char *response;
};

struct data {
    int run;			/* which run */
    int thread; 		/* Thread number */
    int read;			/* number of bytes read */
    int bread;			/* total amount of entity body read */
    int ctime;			/* time in ms to connect */
    int rtime;			/* time in ms for http request */
    int time;			/* time in ms for full req/resp interval */

    char *request;
    char *request_headers;

    char *response_headers;
    char *response;
};

struct threadval {
    int run;			/* which run */
    int url;			/* which url are we testing */
    int thread; 		/* Thread number */
};

/* --------------------- GLOBALS ---------------------------- */

struct global {
    int concurrency;		/* Number of multiple requests to make */
    int *repeats;		/* Number of time to repeat for each run */
    int requests;		/* the max of the repeats */
    double tlimit;		/* global time limit, in seconds */
    struct timeval min_tlimit;	/* minimum of all time limits */

src/apachebench/types.h  view on Meta::CPAN

    char **req_headers;		/* optional arbitrary request headers to add */
    char ***auto_cookies;	/* cookies extracted from response_headers for the run, i.e. set by http server */
    bool *use_auto_cookies;	/* whether to use auto_cookie feature for the run */
    int *postlen;		/* length of data to be POSTed */
    int *totalposted;		/* total number of bytes posted, inc. headers*/

    int *good, *failed;		/* number of good and bad requests */
    int *started, *finished, *arranged;
				/* numbers of requests  started , */
				/* finished or arranged for each url*/
    int **which_thread;		/* which thread is available */
    struct threadval *ready_to_run_queue;
    int head, tail, done, need_to_be_done;

    int priority;
    int *order;
    int *buffersize;
    int *memory;
    int number_of_urls, number_of_runs;

    char version[8];		/* to store perl module version */
    char warn_and_error[WARN_BUFFSIZE];  /* warn and error message returned to perl */



( run in 0.389 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )