Commit | Line | Data |
---|---|---|
805e021f CE |
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 | RX_SECIDX_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 | } |