Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / multi.example / sample_client.c
CommitLineData
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 */
24static u_long
25GetIpAddress(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
43main(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}