death to register
[openafs.git] / src / rx / multi.example / sample_client.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* Sample program using multi_Rx, to execute calls in parallel to multiple hosts */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16 #include <sys/types.h>
17 #include <netdb.h>
18 #include <netinet/in.h>
19 #include <stdio.h>
20 #include "sample.h"
21 #include "rx/rx_clock.h"
22
23 /* Bogus procedure to get internet address of host */
24 static u_long
25 GetIpAddress(hostname)
26      char *hostname;
27 {
28     struct hostent *hostent;
29     u_long host;
30     hostent = gethostbyname(hostname);
31     if (!hostent) {
32         printf("host %s not found", hostname);
33         exit(1);
34     }
35     if (hostent->h_length != sizeof(u_long)) {
36         printf("host address is disagreeable length (%d)", hostent->h_length);
37         exit(1);
38     }
39     memcpy((char *)&host, hostent->h_addr, sizeof(host));
40     return host;
41 }
42
43 main(argc, argv)
44      char **argv;
45 {
46     struct rx_securityClass *null_securityObject;
47     int i, nHosts = 0;
48     struct {
49         u_long ipaddr;
50         char *name;
51     } host[50];
52     int arg[50];
53     struct rx_connection *conns[50];
54     int nSuccesses = 0;
55     int trials = 1;
56     int verbose = 0;
57     int abort = 0;
58     int msec;
59     struct clock startTime, endTime;
60     int result;
61     argc--;
62     argv++;
63     while (**argv == '-') {
64         if (strcmp(*argv, "-verbose") == 0)
65             verbose = 1;
66         else if (strcmp(*argv, "-count") == 0)
67             trials = atoi(*++argv), argc--;
68         else if (strcmp(*argv, "-abort") == 0)
69             abort = 1;
70         else {
71             fprintf("Unknown option %s\n", *argv);
72             exit(1);
73         }
74         argc--;
75         argv++;
76     }
77     while (argc--) {
78         host[nHosts].name = *argv;
79         host[nHosts].ipaddr = GetIpAddress(*argv);
80         arg[nHosts] = 10000 * (nHosts + 1);     /* a bogus argument to show how an input argument to the multi call can be indexed by multi_i */
81         nHosts++;
82         argv++;
83     }
84
85     rx_Init(0);
86     null_securityObject = rxnull_NewClientSecurityObject();
87     for (i = 0; i < nHosts; i++) {
88         conns[i] =
89             rx_NewConnection(host[i].ipaddr, SAMPLE_SERVER_PORT,
90                              SAMPLE_SERVICE_ID, null_securityObject,
91                              SAMPLE_NULL);
92     }
93
94     clock_NewTime();
95     clock_GetTime(&startTime);
96     for (i = 0; i < trials; i++) {
97         multi_Rx(conns, nHosts) {
98             /* Note that multi_i is available both for arguments (result could also be indexed by multi_i, if you want to keep the results apart, and after the call completes) and in the code which follows the completion of each multi_TEST_Add.  At completion, multi_i will be set to the connection index of the call which completed, and multi_error will be set to the error code returned by that call. */
99             if (verbose)
100                 printf("%s:  About to add %d to %d\n", host[multi_i].name,
101                        arg[multi_i], i * 10, &result);
102             multi_TEST_Add(verbose, arg[multi_i], i * 10, &result);
103             if (verbose)
104                 printf("%s: error %d, %d + %d is %d\n", host[multi_i].name,
105                        multi_error, arg[multi_i], i * 10, result);
106             if (abort && multi_error)
107                 multi_Abort;
108             if (multi_error == 0)
109                 nSuccesses++;
110             else if (!verbose)
111                 printf("%s: error %d\n", host[multi_i].name, multi_error);
112         }
113         multi_End;
114     }
115     clock_NewTime();
116     clock_GetTime(&endTime);
117     msec = clock_ElapsedTime(&startTime, &endTime);
118     printf
119         ("nSuccesses=%d in %d msec; %d msec per iteration for %d iterations over %d hosts\n",
120          nSuccesses, msec, msec / trials, trials, nHosts);
121
122     /* Allow Rx to idle down any calls; it's a good idea, but not essential, to call this routine */
123     rx_Finalize();
124 }