2 * Copyright 2000, International Business Machines Corporation and others.
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
10 /* Sample program using multi_Rx, to execute calls in parallel to multiple hosts */
12 #include <afsconfig.h>
13 #include <afs/param.h>
18 #include <sys/types.h>
20 #include <netinet/in.h>
23 #include "rx/rx_clock.h"
25 /* Bogus procedure to get internet address of host */
27 GetIpAddress(hostname)
30 struct hostent *hostent;
32 hostent = gethostbyname(hostname);
34 printf("host %s not found", hostname);
37 if (hostent->h_length != sizeof(u_long)) {
38 printf("host address is disagreeable length (%d)", hostent->h_length);
41 memcpy((char *)&host, hostent->h_addr, sizeof(host));
48 struct rx_securityClass *null_securityObject;
49 register int i, nHosts = 0;
55 struct rx_connection *conns[50];
57 register int trials = 1;
58 register int verbose = 0;
59 register int abort = 0;
61 struct clock startTime, endTime;
65 while (**argv == '-') {
66 if (strcmp(*argv, "-verbose") == 0)
68 else if (strcmp(*argv, "-count") == 0)
69 trials = atoi(*++argv), argc--;
70 else if (strcmp(*argv, "-abort") == 0)
73 fprintf("Unknown option %s\n", *argv);
80 host[nHosts].name = *argv;
81 host[nHosts].ipaddr = GetIpAddress(*argv);
82 arg[nHosts] = 10000 * (nHosts + 1); /* a bogus argument to show how an input argument to the multi call can be indexed by multi_i */
88 null_securityObject = rxnull_NewClientSecurityObject();
89 for (i = 0; i < nHosts; i++) {
91 rx_NewConnection(host[i].ipaddr, SAMPLE_SERVER_PORT,
92 SAMPLE_SERVICE_ID, null_securityObject,
97 clock_GetTime(&startTime);
98 for (i = 0; i < trials; i++) {
99 multi_Rx(conns, nHosts) {
100 /* 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. */
102 printf("%s: About to add %d to %d\n", host[multi_i].name,
103 arg[multi_i], i * 10, &result);
104 multi_TEST_Add(verbose, arg[multi_i], i * 10, &result);
106 printf("%s: error %d, %d + %d is %d\n", host[multi_i].name,
107 multi_error, arg[multi_i], i * 10, result);
108 if (abort && multi_error)
110 if (multi_error == 0)
113 printf("%s: error %d\n", host[multi_i].name, multi_error);
118 clock_GetTime(&endTime);
119 msec = clock_ElapsedTime(&startTime, &endTime);
121 ("nSuccesses=%d in %d msec; %d msec per iteration for %d iterations over %d hosts\n",
122 nSuccesses, msec, msec / trials, trials, nHosts);
124 /* Allow Rx to idle down any calls; it's a good idea, but not essential, to call this routine */