00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <Basics.H>
00049 #include <SRPC.H>
00050 #include <MultiSRPC.H>
00051 #include <LimService.H>
00052
00053 #include <sstream>
00054
00055 using std::ostream;
00056 using std::istringstream;
00057 using std::endl;
00058 using std::cout;
00059 using std::cerr;
00060
00061
00062 const Text IntfName("1234");
00063 const int IntfVersion = 1;
00064 const int ProcId1 = 1;
00065
00066
00067 static Basics::mutex mu;
00068
00069
00070 const unsigned FirstSize = 1U << 1;
00071 const unsigned LastSize = 1U << 20;
00072 const int NumIterations = 8;
00073
00074 void SyntaxError(const char *msg) throw ()
00075 {
00076 cerr << "Error: " << msg << '\n';
00077 cerr << "SYNTAX: TestBigXfer [ -client | -server ] [ -iters n ]\n";
00078 exit(1);
00079 }
00080
00081 ostream& operator << (ostream &os, const SRPC::failure &f) throw ()
00082 {
00083 mu.lock();
00084 int i;
00085 for (i = 0; i < 70; i++) os << '*'; os << '\n';
00086 os << "SRPC failure (" << f.r << ") :\n";
00087 os << " " << f.msg << '\n';
00088 for (i = 0; i < 70; i++) os << '*'; os << "\n\n";
00089 os.flush();
00090 mu.unlock();
00091 return os;
00092 }
00093
00094 void ClientCall(SRPC *srpc, int numIterations, unsigned len)
00095 throw (SRPC::failure)
00096 {
00097 mu.lock();
00098 cout << "Calling Proc1\n";
00099 cout << " len = " << len << '\n';
00100 cout << " buffs = " << numIterations << '\n';
00101 cout << " total = " << numIterations * len << '\n';
00102 (cout << '\n').flush();
00103 mu.unlock();
00104
00105 char* buff = NEW_PTRFREE_ARRAY(char, len);
00106 srpc->start_call(ProcId1, IntfVersion);
00107 srpc->send_int(numIterations);
00108 for (int i = 0; i < numIterations; i++) {
00109 srpc->send_bytes(buff, len);
00110 }
00111 srpc->send_end();
00112 unsigned res = srpc->recv_int();
00113 assert(res == (len * numIterations));
00114 srpc->recv_end();
00115 delete buff;
00116
00117 mu.lock();
00118 cout << "Returned Proc1\n";
00119 (cout << '\n').flush();
00120 mu.unlock();
00121 }
00122
00123 void Client(int numIterations, const char *server) throw ()
00124 {
00125 MultiSRPC multi(IntfName);
00126 try {
00127 for (unsigned len = FirstSize; len <= LastSize; len <<= 1) {
00128
00129 SRPC *srpc;
00130 MultiSRPC::ConnId connId;
00131 connId = multi.Start(server, srpc);
00132
00133
00134 ClientCall(srpc, numIterations, len);
00135
00136
00137 multi.End(connId);
00138 }
00139 } catch (SRPC::failure f) {
00140 cout << f;
00141 }
00142 }
00143
00144 void ServerFailureCallback(SRPC *srpc, const SRPC::failure &f, void *arg)
00145 throw ()
00146 {
00147 cout << f;
00148 }
00149
00150 void Proc1(SRPC *srpc) throw (SRPC::failure)
00151 {
00152 int len, total = 0;
00153 char *buff;
00154
00155 int numIterations = srpc->recv_int();
00156 for (int i = 0; i < numIterations; i++) {
00157 buff = srpc->recv_bytes( len);
00158 delete buff;
00159 total += len;
00160 }
00161 srpc->recv_end();
00162
00163 mu.lock();
00164 cout << "Called Proc1\n";
00165 cout << " len = " << len << '\n';
00166 cout << " buffs = " << numIterations << '\n';
00167 cout << " total = " << total << '\n';
00168 (cout << '\n').flush();
00169 mu.unlock();
00170
00171 srpc->send_int(total);
00172 srpc->send_end();
00173
00174 mu.lock();
00175 cout << "Returned Proc1\n";
00176 (cout << '\n').flush();
00177 mu.unlock();
00178 }
00179
00180 void ServerCallback(SRPC *srpc, int procId, void *arg)
00181 throw (SRPC::failure)
00182 {
00183 switch (procId) {
00184 case ProcId1: Proc1(srpc); break;
00185 default: assert(false);
00186 }
00187 }
00188
00189 void Server() throw ()
00190 {
00191
00192 const int MaxRunning = 10, MaxBlocked = 10;
00193 LimService ls(IntfName, IntfVersion, MaxRunning, MaxBlocked,
00194 ServerCallback, ServerFailureCallback);
00195 Basics::thread th = ls.Forked_Run();
00196
00197
00198 mu.lock();
00199 (cout << "Server ready...\n\n").flush();
00200 mu.unlock();
00201
00202
00203 (void) th.join();
00204 }
00205
00206 int main(int argc, char *argv[])
00207 {
00208 enum Kind { NoKind, ClientKind, ServerKind };
00209 Kind kind = NoKind;
00210 int arg = 1;
00211 int numIterations = NumIterations;
00212 const char *server = 0;
00213
00214 while (arg < argc) {
00215 if (strcmp(argv[arg], "-client") == 0) {
00216 kind = ClientKind;
00217 } else if (strcmp(argv[arg], "-server") == 0) {
00218 kind = ServerKind;
00219 } else if (strcmp(argv[arg], "-iters") == 0) {
00220 if (++arg >= argc) SyntaxError("no argument for '-iters' switch");
00221 istringstream istr(argv[arg]);
00222 istr >> numIterations;
00223 } else if (!server && (kind == ClientKind)) {
00224 server = argv[arg];
00225 } else {
00226 Text msg = "unrecognized switch: \"";
00227 msg += argv[arg];
00228 msg += "\"";
00229 SyntaxError(msg.cchars());
00230 }
00231 arg++;
00232 }
00233 if(!server)
00234 {
00235 server = "localhost";
00236 }
00237 switch (kind) {
00238 case ClientKind: Client(numIterations, server); break;
00239 case ServerKind: Server(); break;
00240 default:
00241 SyntaxError("you must specify '-client' or '-server'");
00242 break;
00243 }
00244 return 0;
00245 }