diff options
Diffstat (limited to 'ACE/apps/JAWS/clients/WebSTONE/src/webclient.c')
-rw-r--r-- | ACE/apps/JAWS/clients/WebSTONE/src/webclient.c | 1299 |
1 files changed, 0 insertions, 1299 deletions
diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c b/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c deleted file mode 100644 index 42084842904..00000000000 --- a/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* $Id$ */ -/************************************************************************** - * * - * Copyright (C) 1995 Silicon Graphics, Inc. * - * * - * These coded instructions, statements, and computer programs were * - * developed by SGI for public use. If any changes are made to this code* - * please try to get the changes back to the author. Feel free to make * - * modifications and changes to the code and release it. * - * * - **************************************************************************/ - -/* FUZZ: disable check_for_math_include */ -/* FUZZ: disable check_for_improper_main_declaration */ - -#include <thread.h> - -#include <stdio.h> - -#ifdef WIN32 -#include <windows.h> -#include <winsock.h> -#include <time.h> -#include <process.h> -#include <io.h> -#endif /* WIN32 */ - -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> - -#ifndef WIN32 -#include <netdb.h> -#include <unistd.h> -#endif /* WIN32 */ - -#include <time.h> -#include <math.h> - -#ifndef WIN32 -#include <sys/param.h> -#endif /* WIN32 */ - -#include <sys/types.h> - -#ifndef WIN32 -#include <sys/ipc.h> -#include <sys/shm.h> -#include <sys/errno.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/wait.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif /* WIN32 */ - -#include <ctype.h> - -#include "sysdep.h" -#include "bench.h" - -#define _BSD_SIGNALS -#define INFINITY 100000000 -#define DEFAULTWWWPORT 80 -#define LOG_FILE "logfile" -#ifdef WIN32 -#define DEBUG_FILE "c:/tmp/webstone-debug" -#else -#define DEBUG_FILE "/tmp/webstone-debug" -#endif /* WIN32 */ -#define NCCARGS 4096 - -/* global variables */ - - THREAD FILE *debugfile = stderr; - page_list_t *load_file_list; /* actually a dynamic array */ - -int amclient = 0; -int havewebserver = 0; -int haveproxyserver = 0; -int savefile = 0; -NETPORT portnum = DEFAULTWWWPORT; -int timeexpired = 0; -int debug = 0; -long int number_of_pages = 0; -char webmaster[MAXHOSTNAMELEN]; -char webserver[MAXHOSTNAMELEN]; -char proxyserver[MAXHOSTNAMELEN]; - - -#ifdef WIN32 -HANDLE hSemaphore; -int CounterSemaphore = 0; /* counter semaphore for children */ -#endif /* WIN32 */ - -static void ClientThread(void *); - -/* used to bypass DNS/YP name resolution for every page */ -struct hostent webserv_phe, webmast_phe; -struct protoent webserv_ppe, webmast_ppe; -unsigned long webserv_addr, webmast_addr; -short webserv_type, webmast_type; /* socket type */ - -/* End of globals */ - - -static void -usage(const char *progname) -{ - returnerr("Usage: %s [-d] [-w webserver] [-p port_num]\n", - progname); - returnerr("\t[-c masterhost:port] [-t run_time | -l loops]\n"); - returnerr("\t[-n numclients] [-R]\n"); - returnerr("\t[-f config_file] [-u uilfile | url ...]\n"); - errexit("\n"); -} /* END usage() */ - -static void -alarmhandler(void) -{ - /* RECEIVED AN ALARM SIGNAL */ - timeexpired = 1; -} /* END alarmhandler() */ - -#ifndef WIN32 -static void -childhandler(void) -{ - int status; - - /* RECEIVED A SIGNAL THAT A CHILD PROCESS HAS DIED */ - D_PRINTF( "A child process has died\n" ); - while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0) - { - /* do nothing */ - ; - } -} /* END childhandler() */ -#endif /* WIN32 */ - - -/* look up the host name and protocol - * called once by main() since all threads - * use the same protocol and address - */ - -int resolve_addrs(char *host, char *protocol, struct hostent *host_phe, struct protoent *proto_ppe, unsigned long *addr, - short *type) { -struct hostent *phe; -struct protoent *ppe; - - /* if IP address given, convert to internal form */ - if (host[0] >= '0' && host[0] <= '9') { - *addr = inet_addr(host); - if (*addr == INADDR_NONE) - return(returnerr("Invalid IP address %s\n", host)); - - } else { - /* look up by name */ - phe = gethostbyname(host); - if (phe == 0) - { - D_PRINTF( "Gethostbyname failed: %s", neterrstr() ); - return(returnerr("Can't get %s host entry\n", host)); - } - memcpy(host_phe, phe, sizeof(struct hostent)); - memcpy((char *)addr, phe->h_addr, sizeof(*addr)); - } - - /* Map protocol name to protocol number */ - ppe = getprotobyname(protocol); - - if (ppe == 0) - { - D_PRINTF( "protobyname returned %d\n", ppe ); - return(returnerr("Can't get %s protocol entry\n",protocol)); - } - memcpy(proto_ppe, ppe, sizeof(struct protoent)); - - D_PRINTF( "Protocol number %d\n", ppe->p_proto ); - - /* Use protocol to choose a socket type */ - if (strcmp(protocol,"udp") == 0) - { - *type = SOCK_DGRAM; - } - else - { - *type = SOCK_STREAM; - D_PRINTF( "Choosing SOCK_STREAM %d type %d %s\n", - SOCK_STREAM, *type, neterrstr() ); - } - - return 0; -} - -/* connect to a socket given the hostname and protocol */ -SOCKET -connectsock(char *host, NETPORT portnum, char *protocol) - { - struct sockaddr_in sin; /* an Internet endpoint address */ - SOCKET s; /* socket descriptor */ - int type; /* socket type */ - short proto; - int returnval; /* temporary return value */ - - D_PRINTF( "Beginning connectsock; host=%s port=%d proto=%s\n", host, - portnum, protocol ); - - sin.sin_family = AF_INET; - memset((char *)&sin, 0, sizeof(sin)); - D_PRINTF( "Zeroed address structure\n" ); - - sin.sin_port = htons(portnum); - D_PRINTF( "Set port number %d\n", portnum ); - - /* get the contact information */ - if (strcmp(host, webserver) == 0) { - sin.sin_addr.S_ADDR = webserv_addr; - sin.sin_family = PF_INET; - proto = webserv_ppe.p_proto; - type = webserv_type; - } else if (strcmp(host, webmaster) == 0) { - sin.sin_addr.S_ADDR = webmast_addr; - sin.sin_family = PF_INET; - proto = webmast_ppe.p_proto; - type = webmast_type; - } else { - struct hostent host_phe; - struct protoent host_ppe; - unsigned long host_addr; - short host_type; /* socket type */ - - if (resolve_addrs(host, "tcp", &host_phe, &host_ppe, &host_addr, &host_type)) - return returnerr("Can't resolve hostname %s in get()\n", host); - sin.sin_addr.S_ADDR = host_addr; - sin.sin_family = PF_INET; - proto = host_ppe.p_proto; - type = host_type; - } - - /* Allocate a socket */ - s = socket(PF_INET, type, proto); - D_PRINTF( "Socket %d returned %d, %s\n", - type, s, neterrstr() ); - - if (BADSOCKET(s)) - { - D_PRINTF( "Can't create socket: %s\n",neterrstr() ); - return BADSOCKET_VALUE; - } - - /* Connect the socket */ - D_PRINTF( "Trying to connect %d with size %d, %s\n", - s, sizeof(sin), neterrstr() ); - D_PRINTF( "Address is family %d, port %d, addr %s\n", - sin.sin_family, ntohs(sin.sin_port), - inet_ntoa(sin.sin_addr) ); - - returnval = connect(s, (struct sockaddr *)&sin, sizeof(sin)); - D_PRINTF( "Connect returned %d, %s\n", - returnval, neterrstr() ); - if (returnval < 0) - { - D_PRINTF( "Can't connect: %s\n", neterrstr() ); - NETCLOSE(s); - return BADSOCKET_VALUE; - } - - /* all done, returning socket descriptor */ - D_PRINTF( "Returning %d from connectsock call\n", s ); - return(s); - -} /* END connectsock() */ - -SOCKET -connecttomaster(char *str) -{ - char *tempch; - SOCKET sock; - char msg[100]; - char ConnectStr[100]; /* Fix to handle multiple threads */ - int tries; - - strcpy(ConnectStr, str); - - /* - * BREAK UP THE connectstr INTO A HOSTNAME/HOST-IP AND A PORT NUMBER. - */ - if((tempch = strpbrk(ConnectStr,":")) == 0) - { - /* - * INCORRECT FORMAT OF ConnectStr. CORRECT FORMAT IS - * HOSTNAME:PORT OR HOST-IP:PORT - */ - D_PRINTF( "Incorrect format %s: use hostname:port or ip_addr:port\n", - ConnectStr ); - return(returnerr("Incorrect format %s: use host:port or ip_addr:port\n", - ConnectStr)); - } - - /* - * ZERO OUT THE COLON SO WE HAVE TWO STRINGS, THE HOSTNAME AND THE PORT - */ - *tempch = '\0'; - tempch++; - - /* loop here to connect to webmaster - TCP/IP allows no more than 5 - * connection requests outstanding at once and thus the webmaster may - * reject a connection if there are a lot of client processes - */ -#define MAXTRIES 30 -#define TRYDELAY_SEC 1 - for (tries = 0; tries < MAXTRIES; tries++) { - - sock = connectsock(ConnectStr,(NETPORT)atoi(tempch),"tcp"); - - if (!BADSOCKET(sock)) - break; - - sleep(TRYDELAY_SEC); - } - - if (BADSOCKET(sock)) - { - /* ERROR CONNECTING TO MASTER PROCESS */ - return(returnerr("Could not connect to master process\n")); - } - - /* - * SIGNAL THE MASTER THAT WE ARE READY TO PROCEED. WHEN ALL - * CHILD PROCESSES HAVE CONNECTED AND SENT THIS SIGNAL, - * THE MASTER WILL ISSUE US A GO SIGNAL. - */ - if(NETWRITE(sock,READYSTR,READYSTRLEN) != READYSTRLEN) - { - return(returnerr("Error sending READY message to master")); - } - - memset(msg,0,GOSTRLEN+1); - if(NETREAD(sock,msg,GOSTRLEN) != GOSTRLEN) - { - D_PRINTF( "Error receiving GO message from master: %s\n", neterrstr() - ); - return(returnerr("Error receiving GO message from master\n")); - } - - if(strncmp(GOSTR,msg,GOSTRLEN)) - { - /* - * WE RECEIVED A MESSAGE OTHER THAN GO. PRINT IT OUT AND RETURN ERROR - */ - return(returnerr("Received non-GO message %s\n",msg)); - } - - return(sock); - -} /* END connecttomaster() */ - - -static void -accumstats(rqst_timer_t *rqsttimer, page_stats_t *pagestats, stats_t *timestat) -{ - rqst_stats_t rqststats; - -#define TFMT "%10u:%10u" - /* - * DUMP THE TIMING INFORMATION HERE, OR COMPUTE WHAT YOU WANT TO - * PRINT OUT LATER. - */ - - D_PRINTF( "Total bytes read: %d \t Body size read: %d\n", - rqsttimer->totalbytes, - rqsttimer->bodybytes ); - - D_PRINTF( "Enter time: " TFMT " \t Exit Time: " TFMT "\n", - rqsttimer->entertime.tv_sec, - rqsttimer->entertime.tv_usec, - rqsttimer->exittime.tv_sec, - rqsttimer->exittime.tv_usec ); - D_PRINTF( "Before connect: " TFMT " \t After connect: " TFMT "\n", - rqsttimer->beforeconnect.tv_sec, - rqsttimer->beforeconnect.tv_usec, - rqsttimer->afterconnect.tv_sec, - rqsttimer->afterconnect.tv_usec ); - D_PRINTF( "Before header: " TFMT " \t After header: " TFMT "\n", - rqsttimer->beforeheader.tv_sec, - rqsttimer->beforeheader.tv_usec, - rqsttimer->afterheader.tv_sec, - rqsttimer->afterheader.tv_usec ); - D_PRINTF( "After body: " TFMT "\n", - rqsttimer->afterbody.tv_sec, - rqsttimer->afterbody.tv_usec ); - - rqstat_times(&(rqststats), rqsttimer); - rqstat_sum(&(timestat->rs), &(rqststats)); - rqstat_sum(&(pagestats->rs), &(rqststats)); - - if (rqsttimer->page_number != 999) - { - timestat->page_numbers[rqsttimer->page_number] += 1; - } - -#undef TFMT -} /* END accumstats */ - - -/* - * fetch the set of files that constitute a page - * - * maxcount = the number of files in the WWW page - * pageval = the number of the WWW page (offset in load_file_list[]) - * (if -1, use page # 0 - does this still work?) - * - * returns the number of files retrieved - */ -static int -makeload(int maxcount, int pageval, THREAD rqst_timer_t *timerarray, THREAD stats_t *timestat, THREAD SOCKET mastersock, THREAD page_stats_t *page_stats) -{ - int cnt; - int returnval; - page_stats_t page_stats_tmp; - char server[MAXHOSTNAMELEN]; - - NETPORT loc_portnum; - - D_PRINTF( "Starting makeload(maxcount %d, pageval %d)\n", - maxcount, pageval ); - - strcpy( server, webserver); /* Put in default value */ - - page_stats_init(&page_stats_tmp); - D_PRINTF( "Page stats initialized\n" ); - - for (cnt = 0; cnt < maxcount; cnt++) - { - D_PRINTF( "Loop count %d in makeload()\n", cnt ); - if (pageval == -1) - { - pageval = cnt; - } - if (timeexpired) - { - break; - } - - /* check for a filename */ - if (strlen(load_file_list[pageval].filename[cnt]) < 1) - { - D_PRINTF( "Bad filename at pageval %d, count %d\n", - pageval, cnt ); - return(returnerr("Bad filename at pageval %d, count %d\n", - pageval, cnt)); - } - - /* if (load_file_list[pageval].port_number[cnt] != 0) - { - loc_portnum = load_file_list[pageval].port_number[cnt]; - } - else - { - loc_portnum = portnum; - } */ - loc_portnum = portnum; - if ((load_file_list[pageval].servername[cnt] != 0) - && - *load_file_list[pageval].servername[cnt]) - { - D_PRINTF( "Copying URL server %s to server\n", - load_file_list[pageval].servername[cnt] ); - strcpy(server, load_file_list[pageval].servername[cnt]); - } - - if (haveproxyserver) - { - D_PRINTF( "Copying proxy %s to webserver\n", proxyserver ); - strcpy(server, proxyserver); - } - - - D_PRINTF( "Calling get(%s, %d, %s, &(timearray[%d]))\n", - server, loc_portnum, load_file_list[pageval].filename[cnt], - cnt ); - - returnval = get(server, loc_portnum, - load_file_list[pageval].filename[cnt], - &(timerarray[cnt])); - if (returnval < 0) - { - D_PRINTF( "***GET() RETURNED AN ERROR\n" ); - } - - /* - * DID GET() RETURN A VALID TIME? - */ - if ((returnval == 0) && (timerarray[cnt].valid == 2)) - { - timerarray[cnt].page_number = pageval; - - accumstats(&timerarray[cnt], &page_stats_tmp, timestat); - } - else if (!timeexpired) /* INVALID, INCREMENT THE ERROR COUNTER */ - { - D_PRINTF( "GET error counter incremented\n" ); - timestat->rs.totalerrs++; - } - - if (amclient) { - fd_set readfds; - struct timeval timeout; - int rv; - - timeout.tv_sec = 0; - timeout.tv_usec = 0; - FD_ZERO(&readfds); - FD_SET(mastersock, &readfds); - - /* if the webmaster has aborted, quit */ - D_PRINTF("Before select() on webmaster socket\n"); - if (rv = select(FD_SETSIZE, &readfds, 0, 0, &timeout)) { - D_PRINTF("select() returned %d\n", rv); - D_PRINTF("Client terminating at request of webmaster\n"); - exit(2); - } - } - - } /* END for cnt */ - - /* - * DO WE HAVE A VALID RETURN FROM GET()? - * WHY NOT USE returnval HERE? - */ - if ((returnval == 0) && - (cnt == load_file_list[pageval].num_of_files) && - (timerarray[cnt-1].valid == 2)) - { - rqst_stats_t *ps_rs; - rqst_stats_t *pst_rs; - - ps_rs = &(page_stats[pageval].rs); - pst_rs = &(page_stats_tmp.rs); - - rqstat_sum(ps_rs, pst_rs); - - page_stats[pageval].totalpages++; - - if (page_stats[pageval].page_size == 0) - { - page_stats[pageval].page_size = (unsigned) - page_stats_tmp.rs.totalbody; - } - } - - D_PRINTF( "\nMakeload output page %d: %d errors, %d pages\n", - pageval, timestat->rs.totalerrs, page_stats[pageval].totalpages ); - D_PRINTF( "Makeload returning %d\n", cnt ); - - return(cnt); - -} /* END makeload() */ - -#ifdef WIN32 -/* close socket library at exit() time */ -void sock_cleanup(void) { - - WSACleanup(); -} -#endif /* WIN32 */ - -/* globalize variables that were in main() */ -long int numfiles = 0; -int testtime = 0; -int numloops = 0; -int numclients = 0; -int record_all_transactions = 0; -int uil_filelist_f = 0; /* filedescriptor of URLs to fetch? */ -int verbose = 0; -int total_weight; -char uil_filelist[NCCARGS]; -char filelist[MAXNUMOFFILES][MAXPATHLEN]; -char configfile[MAXPATHLEN]; -char connectstr[MAXHOSTNAMELEN+10]; - -void -ACE_TMAIN(int argc, ACE_TCHAR *argv[]) -{ - int file_count=0; - int getoptch; - int currarg; - extern char *optarg; - extern int optind; - int i, j; - char *tempch; - int err; - -#define SLEEP_USEC 100 -#ifdef WIN32 - WSADATA WSAData; -#else - - struct timeval sleeptime; - - /* set the amount of time that we'll pause before sending a "." to the - webmaster */ - - sleeptime.tv_sec = SLEEP_USEC/1000000; - sleeptime.tv_usec = SLEEP_USEC % 1000000; -#endif /* WIN32 */ - - debugfile = stderr; - -#ifdef WIN32 - MessageBeep(~0U); /* announce our existence */ - MessageBeep(~0U); - MessageBeep(~0U); - - err = WSAStartup(MAKEWORD(1,1), &WSAData); - if (err != 0) { - errexit("Error in WSAStartup()\n"); - } - - atexit(sock_cleanup); - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - - /* create semaphore in locked state */ - hSemaphore = CreateSemaphore(0, 0, 1, 0); - if(hSemaphore == 0) - { - errexit("Create semaphore failed: %d", GetLastError()); - } -#endif /* WIN32 */ - - memset(webserver, 0, sizeof(webserver)); - memset(webmaster, 0, sizeof(webmaster)); - memset(proxyserver, 0, sizeof(proxyserver)); - memset(connectstr, 0, sizeof(connectstr)); - - /* - * PARSE THE COMMAND LINE OPTIONS - */ - - while((getoptch = getopt(argc,argv,"P:f:t:l:p:u:R:w:c:n:sdv")) != EOF) - { - switch(getoptch) - { - case 'c': - sprintf(connectstr, "%s", optarg); - amclient = 1; - printf("%s", OKSTR); /* sent back to webmaster */ - fflush(stdout); - break; - case 'd': - debug = 0; /* sumedh */ - break; - case 'f': - sprintf(configfile, "%s", optarg); - break; - case 'l': - numloops = atoi(optarg); - break; - case 'n': - numclients = atoi(optarg); - break; - case 'u': - sprintf(uil_filelist, "%s", optarg); - uil_filelist_f = 1; - break; - case 'p': - portnum = atoi(optarg); - break; - case 's': - savefile = 1; - break; - case 't': - testtime = 60 * atoi(optarg); - break; - case 'v': - verbose = 1; - break; - case 'w': - havewebserver = 1; - sprintf(webserver,"%s",optarg); - break; - case 'P': - haveproxyserver = 1; - sprintf(proxyserver, "%s", optarg); - break; - case 'R': - record_all_transactions = 1; - break; - default: - usage(argv[0]); - } - } - - returnerr("Client begins...\n"); - D_PRINTF( "Running in debug mode\n\n" ); - - /* print the command line */ - for (i = 0; i < argc; i++) - D_PRINTF( "%s ", argv[i] ); - D_PRINTF( "\n\n" ); - - if(testtime && numloops) - { - /* - * EITHER numloops OR testtime, BUT NOT BOTH. - */ - usage(argv[0]); - } - - if(havewebserver != 1) - { -#ifdef WIN32 - /* - * THE SERVER'S NAME MUST BE SPECIFIED - */ - returnerr("No WWW Server specified\n"); - usage(argv[0]); -#else - /* IF IT ISN'T, WE ASSUME LOCALHOST */ - sprintf(webserver, "%s", "localhost"); - havewebserver = 1; -#endif /* WIN32 */ - } - - currarg = optind; - numfiles = 0; - while(currarg != argc) - { - /* - * GET THE URLS TO RETRIEVE. - */ - if (numfiles == MAXNUMOFFILES) { - returnerr("Maximum of %d files on the command line.\n"); - usage(argv[0]); - } - sscanf(argv[currarg],"%s",filelist[numfiles]); - numfiles++; - currarg++; - } - - if ((numfiles != 0) && uil_filelist_f) - { - returnerr("Both a filelist and UIL specified.\n"); - usage(argv[0]); - } - - if((numfiles == 0) && !(uil_filelist_f)) - { - /* - * AT LEAST ONE FILE MUST BE SPECIFIED - */ - returnerr("No UIL resources or filelist specified \n"); - usage(argv[0]); - } - - if((numloops == 0) && (testtime == 0)) - { - /* - * NO SPECIFIED NUMBER OF LOOPS, AND NO TEST TIME - */ - usage(argv[0]); - } - if(numclients > MAXPROCSPERNODE || numclients < 1) - { - returnerr("Number of Clients must be between 1 and %d\n", MAXPROCSPERNODE); - exit(1); - } - - /* allow use of IP address */ - if(amclient) { - if((tempch = strpbrk(connectstr,":")) == 0) - { - /* - * INCORRECT FORMAT OF ConnectStr. CORRECT FORMAT IS - * HOSTNAME:PORT OR HOST-IP:PORT - */ - D_PRINTF( "Incorrect format %s: use hostname:port or ip_addr:port\n", - connectstr ); - returnerr("Incorrect format %s: use host:port or ip_addr:port\n", connectstr); - exit(1); - } else { - strncpy(webmaster, connectstr, tempch-connectstr); - } - if(resolve_addrs(webmaster, "tcp", &webmast_phe, &webmast_ppe, &webmast_addr, &webmast_type)) - exit(1); - } - - if (haveproxyserver) - { - D_PRINTF( "Copying proxy %s to webserver\n", proxyserver ); - strcpy(webserver, proxyserver); - } - - if (resolve_addrs(webserver, "tcp", &webserv_phe, &webserv_ppe, &webserv_addr, &webserv_type)) - exit(1); - - /* - * INITIALIZE DATA - */ - /* allocate space for dynamic arrays */ - load_file_list = - (page_list_t *)mymalloc((MAXNUMOFPAGES)*sizeof(page_list_t)); - - if (uil_filelist_f) - { - /* take a guess at the number of URLs in the file */ - D_PRINTF( "About to parse filelist %s\n", uil_filelist ); - number_of_pages = count_file_list(uil_filelist); - numfiles = 1; - - /* IF WE HAVE A FILELIST, PARSE IT */ - /* allocate memory */ - D_PRINTF( "Allocating page list: %ld by %d\n", - number_of_pages, numfiles ); - for (i=0; i<number_of_pages; i++) - { - for (j=0; j<MAXNUMOFFILES; j++) - { - load_file_list[i].servername[j] = - (char *)mymalloc(URL_SIZE); - load_file_list[i].filename[j] = - (char *)mymalloc(URL_SIZE); - } - } - - D_PRINTF( "Parsing file list: %s\n", uil_filelist ); - parse_file_list(uil_filelist, load_file_list, - &number_of_pages, &numfiles); - /* free memory for pages that won't be used? */ - D_PRINTF( "Actual page list: %ld by %d\n", - number_of_pages, MAXNUMOFFILES ); - - D_PRINTF( "Setting up weighting for %ld pages\n", - number_of_pages ); - total_weight = load_percent(load_file_list, number_of_pages); - /* total_weight = load_percent(load_file_list, number_of_pages, pages); */ - } - else - { - /* no uil file */ - number_of_pages = numfiles; - } - - if (number_of_pages < 1) - { - /* no pages - exit */ - D_PRINTF( "No valid URLs found\n" ); - errexit("No valid URLs found\n"); - } - -#ifndef WIN32 - /* - * IF WE ARE TO FORK ADDITIONAL CLIENTS ON THIS MACHINE, - * WE MUST DO IT BEFORE WE CONNECT TO THE MASTER. - * - * FIRST, SET UP SIGNAL HANDLING - */ - signal(SIGCHLD, childhandler); - for(i = 0; i < numclients; i++) - { - thr_create (0, 0, ClientThread, 0, THR_BOUND, 0); - - /* switch(fork()) - { - case 0: - numclients = 1; - ClientThread(0); - exit(0); - break; - case -1: - errexit("Error forking child processes\n"); - exit(1); - default: - break; - } */ - select(0,(fd_set *)0,(fd_set *)0, (fd_set *)0, &sleeptime); - } - - /* - * Wait for all children to exit. - */ - - while (thr_join(0, 0, 0) == 0); - - /* for(;;) - { - int pid = wait((int*)0); - if ((pid == -1) && errno == ECHILD) break; - } */ -#else - /* start threads on NT */ - for (i = 0; i < numclients; i++) - { - if (_beginthread(ClientThread, 0, 0) == -1) - { - errexit("_beginthread failed: %d", GetLastError()); - } - } -#endif /* WIN32 */ - -#ifdef WIN32 - /* wait for children to get to sync point */ - while (CounterSemaphore < numclients) - sleep(1); - CounterSemaphore = 0; - - /* start all children simultaneously */ - ReleaseSemaphore(hSemaphore, 1, 0); - - if (testtime) { - sleep(testtime); - alarmhandler(); /* signal end of test to threads */ - } - - /* - * Wait for all threads to exit. - */ - while (CounterSemaphore < numclients) - sleep(1); - - CloseHandle(hSemaphore); -#endif /* WIN32 */ - - return; -} /* end main() */ - -void ClientThread(void *dummy) -{ - - THREAD FILE *logfile; - - THREAD stats_t timestat; - - THREAD rqst_timer_t timerarray[MAXNUMOFFILES]; - THREAD SOCKET mastersock = BADSOCKET_VALUE; /* connection to webmaster */ - - - THREAD page_stats_t *page_stats; /* actually a dynamic array */ - - int loopcnt = 0; - int filecnt; - int loop; - int ran_number; - int page_index; - int page_number; - int file_count = 0; - char file_name[50]; - struct timeval runningtime; - time_t junk; - int i; - int returnval; - - /* - * INITIALIZE DATA - */ - - page_stats = - (page_stats_t *)mymalloc((number_of_pages)*sizeof(page_stats_t)); - - for (i=0; i < number_of_pages; i++) { - page_stats_init(&(page_stats[i])); - } - - if (debug) - { - /* - * OPEN A DEBUG FILE - */ - fflush(stderr); - sprintf(file_name, "%s.%d", DEBUG_FILE, (int)getpid()); - debugfile = fopen(file_name, "w+"); - if (debugfile == 0) - errexit("Can't open debug file\n"); - D_PRINTF( "Running in debug mode, %d\n",amclient ); - } - - if (record_all_transactions) - { - /* - * OPEN A LOG FILE. - */ - sprintf(file_name, "%s%d", LOG_FILE, (int)getpid()); - returnerr("Log file is %s\n", file_name); - logfile = fopen(file_name, "w+"); - } - - /* Initialize random number generator */ - junk = getpid (); - rand_r(&junk); - D_PRINTF( "Random seed: %d\n", junk ); - - for (i=0; i < MAXNUMOFFILES; i++) - { - rqtimer_init(&(timerarray[i])); - } - stats_init(×tat); - - D_PRINTF( "Number of files %d\n", numfiles ); - - timestat.total_num_of_files = numfiles; - - if (amclient) - { - /* - * WE ARE A CLIENT PROCESS. (i.e. WE ARE NOT RUN BY A USER, BUT BY - * THE MASTER WWWSTONE PROCESS. WE NEED TO CONNECT TO THE - * MASTER WHO WILL SYNCHRONIZE ALL THE CLIENTS. - */ - D_PRINTF( "Trying to connect with %s\n",connectstr ); - - mastersock = connecttomaster(connectstr); - - D_PRINTF( "connecttomaster returns %d, %s\n", - mastersock, neterrstr() ); - - if(BADSOCKET(mastersock)) - { - /* - * ERROR CONNECTING TO THE MASTER. ABORT. - */ - errexit("Error connecting to the master: %s\n", neterrstr()); - } - } /* END IF CLIENT */ - -#ifdef WIN32 - /* Tell parent we're ready */ - InterlockedIncrement(&CounterSemaphore); - - /* Wait for main() thread to release us */ - WaitForSingleObject(hSemaphore, INFINITE); - ReleaseSemaphore(hSemaphore, 1, 0); -#endif /* WIN32 */ - if (testtime != 0) - { - /* - * IF RUNNING A TIMED TEST, WE WILL LOOP - * UNTIL THE ALARM GOES OFF. - * WE'LL ALSO NEED TO SET THE SIGNAL HANDLER - */ -#ifndef WIN32 - /*signal(SIGALRM, alarmhandler);*/ - /* - * SEND SIGALRM IN testtime SECONDS - */ - /*alarm(testtime);*/ -#endif /* WIN32 */ - } - - /* - * AND THEY'RE OFF... - */ - - if (testtime) - numloops = INFINITY; - GETTIMEOFDAY(&(timestat.starttime), &(timestat.starttimezone)); - - /* LOOP UNTIL WE HIT numloops, OR WE RUN OUT OF TIME */ - for(loopcnt = 0; (loopcnt < numloops) && !timeexpired; loopcnt++) - { - /* - * THIS IS WHERE LOAD TESTING IS DONE. - * GET A RANDOM NUMBER, THEN INDEX INTO THE - * PAGE, AND THEN REQUEST THAT SET OF FILES. - */ - if (uil_filelist_f) /* HAVE FILELIST */ - { - D_PRINTF( "Have filelist\n" ); - /* if (testtime != 0) /* RUNNING IN TIMED MODE */ - if (1) - { - D_PRINTF( "Running in timed mode\n" ); - /* random number between 0 and totalweight-1 */ - junk = getpid (); - ran_number = (rand_r(&junk) % total_weight); - D_PRINTF( "random %ld\n", ran_number ); - - /* loop through pages, find correct one - * while ran_number is positive, decrement it - * by the load_num of the current page - * example: ran_number is 5, pages have weights of 10 and 10 - * first iteration page_index = 0, ran_number = -5 - * iteration halted, page_index = 0 - */ - page_index = -1; - while (ran_number >= 0) - { - page_index++; - D_PRINTF( "Current page index %d: %ld - %d\n", - page_index, ran_number, - load_file_list[page_index].load_num - ); - ran_number -= load_file_list[page_index].load_num; - } - - if (page_index >= number_of_pages) { page_index--; } - - D_PRINTF( "Final page index %d\n", page_index ); - filecnt = makeload(load_file_list[page_index].num_of_files, - page_index, timerarray, ×tat, mastersock, page_stats); - testtime = 1; - } - else /* NOT RUNNING IN TIMED MODE */ - { - for (page_number = 0; - page_number < number_of_pages; - page_number++) - { - filecnt = makeload(load_file_list[page_number].num_of_files, - page_number, timerarray, ×tat, mastersock, page_stats); - - } /* END for page_number */ - } /* END if/else TIMED MODE */ - } - else /* NO FILELIST */ - { - D_PRINTF( "No filelist\n" ); - /* - * LOOP THROUGH UNTIL numfiles TIMES OR UNTIL TIMER EXPIRES - * AND ALARM SETS filecnt TO INFINITY. - */ - - /* does this still work?? */ - /* filecnt = makeload(numfiles, -1, timerarray); */ - } /* END if HAVE FILELIST */ - - if (filecnt > 0) - file_count += filecnt; - - } /* END while loopcnt */ - - GETTIMEOFDAY(&(timestat.endtime), &(timestat.endtimezone)); - D_PRINTF( "Test run complete\n" ); - signal(SIGALRM, 0); - - if (testtime == 0) - { - numfiles = loopcnt; - - if (uil_filelist_f) - { - numfiles = file_count; - } - } - - /* This option ( "-R" ) looks broken (e.g. l > 50) -- JEF 2/15/96 */ - if (record_all_transactions) - { - /* - * DUMP THE LOG FILE INFORMATION. - */ - for (loop=0; loop < (loopcnt * file_count); loop++) - { - fprintf(logfile, " entertime \t%d.%d\n" - " beforeconnect \t%d.%d\n" - " afterconnect \t%d.%d\n" - " beforeheader \t%d.%d\n" - " afterheader \t%d.%d\n" - " afterbody \t%d.%d\n" - " exittime \t%d.%d\n" - " total bytes \t%d\n" - " body bytes\t%d\n", - timerarray[loop].entertime.tv_sec, - timerarray[loop].entertime.tv_usec, - timerarray[loop].beforeconnect.tv_sec, - timerarray[loop].beforeconnect.tv_usec, - timerarray[loop].afterconnect.tv_sec, - timerarray[loop].afterconnect.tv_usec, - timerarray[loop].beforeheader.tv_sec, - timerarray[loop].beforeheader.tv_usec, - timerarray[loop].afterheader.tv_sec, - timerarray[loop].afterheader.tv_usec, - timerarray[loop].afterbody.tv_sec, - timerarray[loop].afterbody.tv_usec, - timerarray[loop].exittime.tv_sec, - timerarray[loop].exittime.tv_usec, - timerarray[loop].totalbytes, - timerarray[loop].bodybytes); - } /* end for loop */ - } /* end if recording all transactions */ - - D_PRINTF( "total errors: %d\n",timestat.rs.totalerrs ); - /* gethostname(timestat.hostname,MAXHOSTNAMELEN); */ - /* D_PRINTF( "Test for host: %s\n",timestat.hostname ); */ - D_PRINTF( "Server is: %s running at port number: %d\n", - webserver,portnum ); - - /* sprintf(timestat.hostname,"%s:%d",timestat.hostname,getpid()); */ - if (amclient) /* CLIENT TO A WEBMASTER */ - { - char *stats_as_text; - - /* - * SEND THE TIMING DATA TO THE MASTER - */ - stats_as_text = stats_to_text(×tat); - D_PRINTF( "stats_to_text returned %s\n", stats_as_text ); - - returnval = senddata(mastersock, stats_as_text, - SIZEOF_STATSTEXTBASE + number_of_pages*SIZEOF_DOUBLETEXT); - D_PRINTF( "Wrote time stats to master %d\n", returnval ); - - if (returnval < 1) - { - D_PRINTF( "Error while writing time stats: %s\n", - neterrstr() ); - errexit("Error while writing time stats: %s\n", - neterrstr()); - } - - if (uil_filelist_f) - /* write pagestats */ - { - char *page_stats_as_text; - for (i = 0; i < number_of_pages; i++) - { - D_PRINTF( "On page_stats[%d]\n", i ); - page_stats_as_text = page_stats_to_text(&page_stats[i]); - returnval = strlen(page_stats_as_text); - D_PRINTF( "page_stats_to_text[%d] returned %d\n", - i, returnval ); - returnval = senddata(mastersock, page_stats_as_text, - SIZEOF_PAGESTATSTEXT); - if (returnval < 1) - { - D_PRINTF( "Error while writing page_stats[%d]: %s\n", - i, neterrstr() ); - errexit("Error while writing page_stats[%d]: %s\n", - i, neterrstr()); - } /* end if */ - D_PRINTF( "Wrote %d bytes of page_stats[%d] to master\n", - returnval, i ); - } /* end for */ - } /* end if filelist */ - - D_PRINTF( "About to close socket\n" ); - if (NETCLOSE(mastersock)) - D_PRINTF( "Close socket error: %s\n", neterrstr() ); - } - else /* NOT A CLIENT TO A WEBMASTER */ - { - if (testtime) - { - printf("Test ran for: %d minutes\n",(testtime/60)); - } - else - { - printf("Test ran for: %d iterations.\n",numloops); - } - compdifftime(&(timestat.endtime), &(timestat.starttime), - &(runningtime)); - printf("Total time of test (sec) %d.%d\n", runningtime.tv_sec, - runningtime.tv_usec); - printf("Files retrieved per iteration: %d\n",numfiles); /* 'per iteration' */ - printf("----------------------------------\n"); - printf("Totals:\n\n"); - rqstat_print(&(timestat.rs)); - - if (timestat.rs.totalconnects == 0) - goto end; - printf("Thruput = %5.2lf Kbytes/sec\n", - thruputpersec(timestat.rs.totalbytes, &runningtime) / 1000); - - if (uil_filelist_f && numloops && verbose) - { - for (loop = 0; loop < number_of_pages; loop++) - { - if (timestat.page_numbers[loop] != 0) - { - printf ("===============================================================================\n"); - printf ("Page # %d\n\n", loop); - printf ("Total number of times page was hit %d\n", - page_stats[loop].totalpages); - rqstat_print(&(page_stats[loop].rs)); - printf ("Page size %d \n", page_stats[loop].page_size); - printf ("===============================================================================\n\n"); - } /* END if timestat */ - } /* END for loop */ - } /* END if filelist */ - } /* END if client */ - -end: - if(record_all_transactions) - fclose(logfile); - if(debug) - { - D_PRINTF( "Client exiting.\n" ); - fclose(debugfile); - } - -#ifdef WIN32 - /* tell parent we're done */ - InterlockedIncrement(&CounterSemaphore); -#endif /* WIN32 */ - -} /* END ClientThread() */ |