VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/tmocon.c@ 22683

最後變更 在這個檔案從22683是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.4 KB
 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/*
3 * The contents of this file are subject to the Mozilla Public
4 * License Version 1.1 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of
6 * the License at http://www.mozilla.org/MPL/
7 *
8 * Software distributed under the License is distributed on an "AS
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10 * implied. See the License for the specific language governing
11 * rights and limitations under the License.
12 *
13 * The Original Code is the Netscape Portable Runtime (NSPR).
14 *
15 * The Initial Developer of the Original Code is Netscape
16 * Communications Corporation. Portions created by Netscape are
17 * Copyright (C) 1998-2000 Netscape Communications Corporation. All
18 * Rights Reserved.
19 *
20 * Contributor(s):
21 *
22 * Alternatively, the contents of this file may be used under the
23 * terms of the GNU General Public License Version 2 or later (the
24 * "GPL"), in which case the provisions of the GPL are applicable
25 * instead of those above. If you wish to allow use of your
26 * version of this file only under the terms of the GPL and not to
27 * allow others to use your version of this file under the MPL,
28 * indicate your decision by deleting the provisions above and
29 * replace them with the notice and other provisions required by
30 * the GPL. If you do not delete the provisions above, a recipient
31 * may use your version of this file under either the MPL or the
32 * GPL.
33 */
34
35/***********************************************************************
36**
37** Name: tmocon.c
38**
39** Description: test client socket connection.
40**
41** Modification History:
42** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
43** The debug mode will print all of the printfs associated with this test.
44** The regress mode will be the default mode. Since the regress tool limits
45** the output to a one line status:PASS or FAIL,all of the printf statements
46** have been handled with an if (debug_mode) statement.
47***********************************************************************/
48
49/***********************************************************************
50** Includes
51***********************************************************************/
52/* Used to get the command line option */
53#include "plgetopt.h"
54
55#include "nspr.h"
56#include "pprio.h"
57
58#include "plerror.h"
59#include "plgetopt.h"
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64
65/* for getcwd */
66#if defined(XP_UNIX) || defined (XP_OS2_EMX) || defined(XP_BEOS)
67#include <unistd.h>
68#elif defined(XP_PC)
69#include <direct.h>
70#endif
71
72#ifdef XP_MAC
73#include "prlog.h"
74#define printf PR_LogPrint
75#endif
76
77
78#define BASE_PORT 9867
79
80#define DEFAULT_DALLY 1
81#define DEFAULT_THREADS 1
82#define DEFAULT_TIMEOUT 10
83#define DEFAULT_MESSAGES 100
84#define DEFAULT_MESSAGESIZE 100
85
86static PRFileDesc *debug_out = NULL;
87
88typedef struct Shared
89{
90 PRBool random;
91 PRBool failed;
92 PRBool intermittant;
93 PRIntn debug;
94 PRInt32 messages;
95 PRIntervalTime dally;
96 PRIntervalTime timeout;
97 PRInt32 message_length;
98 PRNetAddr serverAddress;
99} Shared;
100
101static PRIntervalTime Timeout(const Shared *shared)
102{
103 PRIntervalTime timeout = shared->timeout;
104 if (shared->random)
105 {
106 PRIntervalTime quarter = timeout >> 2; /* one quarter of the interval */
107 PRUint32 random = rand() % quarter; /* something in[0..timeout / 4) */
108 timeout = (((3 * quarter) + random) >> 2) + quarter; /* [75..125)% */
109 }
110 return timeout;
111} /* Timeout */
112
113static void CauseTimeout(const Shared *shared)
114{
115 if (shared->intermittant) PR_Sleep(Timeout(shared));
116} /* CauseTimeout */
117
118static PRStatus MakeReceiver(Shared *shared)
119{
120 PRStatus rv = PR_FAILURE;
121 if (PR_IsNetAddrType(&shared->serverAddress, PR_IpAddrLoopback))
122 {
123 char *argv[3];
124 char path[1024 + sizeof("/tmoacc")];
125 (void)getcwd(path, sizeof(path));
126 (void)strcat(path, "/tmoacc");
127#ifdef XP_PC
128 (void)strcat(path, ".exe");
129#endif
130 argv[0] = path;
131 if (shared->debug > 0)
132 {
133 argv[1] = "-d";
134 argv[2] = NULL;
135 }
136 else argv[1] = NULL;
137 if (shared->debug > 1)
138 PR_fprintf(debug_out, " creating accept process %s ...", path);
139 fflush(stdout);
140 rv = PR_CreateProcessDetached(path, argv, NULL, NULL);
141 if (PR_SUCCESS == rv)
142 {
143 if (shared->debug > 1)
144 PR_fprintf(debug_out, " wait 5 seconds");
145 if (shared->debug > 1)
146 PR_fprintf(debug_out, " before connecting to accept process ...");
147 fflush(stdout);
148 PR_Sleep(PR_SecondsToInterval(5));
149 return rv;
150 }
151 shared->failed = PR_TRUE;
152 if (shared->debug > 0)
153 PL_FPrintError(debug_out, "PR_CreateProcessDetached failed");
154 }
155 return rv;
156} /* MakeReceiver */
157
158static void Connect(void *arg)
159{
160 PRStatus rv;
161 char *buffer = NULL;
162 PRFileDesc *clientSock;
163 Shared *shared = (Shared*)arg;
164 PRInt32 loop, bytes, flags = 0;
165 struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
166 debug_out = (0 == shared->debug) ? NULL : PR_GetSpecialFD(PR_StandardError);
167
168 buffer = (char*)PR_MALLOC(shared->message_length);
169
170 for (bytes = 0; bytes < shared->message_length; ++bytes)
171 buffer[bytes] = (char)bytes;
172
173 descriptor.checksum = 0;
174 for (bytes = 0; bytes < shared->message_length; ++bytes)
175 {
176 PRUint32 overflow = descriptor.checksum & 0x80000000;
177 descriptor.checksum = (descriptor.checksum << 1);
178 if (0x00000000 != overflow) descriptor.checksum += 1;
179 descriptor.checksum += buffer[bytes];
180 }
181 descriptor.checksum = PR_htonl(descriptor.checksum);
182
183 for (loop = 0; loop < shared->messages; ++loop)
184 {
185 if (shared->debug > 1)
186 PR_fprintf(debug_out, "[%d]socket ... ", loop);
187 clientSock = PR_NewTCPSocket();
188 if (clientSock)
189 {
190 /*
191 * We need to slow down the rate of generating connect requests,
192 * otherwise the listen backlog queue on the accept side may
193 * become full and we will get connection refused or timeout
194 * error.
195 */
196
197 PR_Sleep(shared->dally);
198 if (shared->debug > 1)
199 {
200 char buf[128];
201 PR_NetAddrToString(&shared->serverAddress, buf, sizeof(buf));
202 PR_fprintf(debug_out, "connecting to %s ... ", buf);
203 }
204 rv = PR_Connect(
205 clientSock, &shared->serverAddress, Timeout(shared));
206 if (PR_SUCCESS == rv)
207 {
208 PRInt32 descriptor_length = (loop < (shared->messages - 1)) ?
209 shared->message_length : 0;
210 descriptor.length = PR_htonl(descriptor_length);
211 if (shared->debug > 1)
212 PR_fprintf(
213 debug_out, "sending %d bytes ... ", descriptor_length);
214 CauseTimeout(shared); /* might cause server to timeout */
215 bytes = PR_Send(
216 clientSock, &descriptor, sizeof(descriptor),
217 flags, Timeout(shared));
218 if (bytes != sizeof(descriptor))
219 {
220 shared->failed = PR_TRUE;
221 if (shared->debug > 0)
222 PL_FPrintError(debug_out, "PR_Send failed");
223 }
224 if (0 != descriptor_length)
225 {
226 CauseTimeout(shared);
227 bytes = PR_Send(
228 clientSock, buffer, descriptor_length,
229 flags, Timeout(shared));
230 if (bytes != descriptor_length)
231 {
232 shared->failed = PR_TRUE;
233 if (shared->debug > 0)
234 PL_FPrintError(debug_out, "PR_Send failed");
235 }
236 }
237 if (shared->debug > 1) PR_fprintf(debug_out, "closing ... ");
238 rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
239 rv = PR_Close(clientSock);
240 if (shared->debug > 1)
241 {
242 if (PR_SUCCESS == rv) PR_fprintf(debug_out, "\n");
243 else PL_FPrintError(debug_out, "shutdown failed");
244 }
245 }
246 else
247 {
248 if (shared->debug > 1) PL_FPrintError(debug_out, "connect failed");
249 PR_Close(clientSock);
250 if ((loop == 0) && (PR_GetError() == PR_CONNECT_REFUSED_ERROR))
251 {
252 if (MakeReceiver(shared) == PR_FAILURE) break;
253 }
254 else
255 {
256 if (shared->debug > 1) PR_fprintf(debug_out, " exiting\n");
257 break;
258 }
259 }
260 }
261 else
262 {
263 shared->failed = PR_TRUE;
264 if (shared->debug > 0) PL_FPrintError(debug_out, "create socket");
265 break;
266 }
267 }
268
269 PR_DELETE(buffer);
270} /* Connect */
271
272int Tmocon(int argc, char **argv)
273{
274 /*
275 * USAGE
276 * -d turn on debugging output (default = off)
277 * -v turn on verbose output (default = off)
278 * -h <n> dns name of host serving the connection (default = self)
279 * -i dally intermittantly to cause timeouts (default = off)
280 * -m <n> number of messages to send (default = 100)
281 * -s <n> size of each message (default = 100)
282 * -t <n> number of threads sending (default = 1)
283 * -G use global threads (default = local)
284 * -T <n> timeout on I/O operations (seconds) (default = 10)
285 * -D <n> dally between connect requests (seconds)(default = 0)
286 * -R randomize the dally types around 'T' (default = no)
287 */
288
289 PRStatus rv;
290 int exitStatus;
291 PLOptStatus os;
292 Shared *shared = NULL;
293 PRThread **thread = NULL;
294 PRIntn index, threads = DEFAULT_THREADS;
295 PRThreadScope thread_scope = PR_LOCAL_THREAD;
296 PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT;
297 PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:");
298
299 shared = PR_NEWZAP(Shared);
300
301 shared->debug = 0;
302 shared->failed = PR_FALSE;
303 shared->random = PR_FALSE;
304 shared->messages = DEFAULT_MESSAGES;
305 shared->message_length = DEFAULT_MESSAGESIZE;
306
307 PR_STDIO_INIT();
308 memset(&shared->serverAddress, 0, sizeof(shared->serverAddress));
309 rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &shared->serverAddress);
310 PR_ASSERT(PR_SUCCESS == rv);
311
312 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
313 {
314 if (PL_OPT_BAD == os) continue;
315 switch (opt->option)
316 {
317 case 'd':
318 if (0 == shared->debug) shared->debug = 1;
319 break;
320 case 'v':
321 if (0 == shared->debug) shared->debug = 2;
322 break;
323 case 'i':
324 shared->intermittant = PR_TRUE;
325 break;
326 case 'R':
327 shared->random = PR_TRUE;
328 break;
329 case 'G':
330 thread_scope = PR_GLOBAL_THREAD;
331 break;
332 case 'h': /* the value for backlock */
333 {
334 PRIntn es = 0;
335 PRHostEnt host;
336 char buffer[1024];
337 (void)PR_GetHostByName(
338 opt->value, buffer, sizeof(buffer), &host);
339 es = PR_EnumerateHostEnt(
340 es, &host, BASE_PORT, &shared->serverAddress);
341 PR_ASSERT(es > 0);
342 }
343 break;
344 case 'm': /* number of messages to send */
345 shared->messages = atoi(opt->value);
346 break;
347 case 't': /* number of threads sending */
348 threads = atoi(opt->value);
349 break;
350 case 'D': /* dally time between transmissions */
351 dally = atoi(opt->value);
352 break;
353 case 'T': /* timeout on I/O operations */
354 timeout = atoi(opt->value);
355 break;
356 case 's': /* total size of each message */
357 shared->message_length = atoi(opt->value);
358 break;
359 default:
360 break;
361 }
362 }
363 PL_DestroyOptState(opt);
364
365 if (0 == timeout) timeout = DEFAULT_TIMEOUT;
366 if (0 == threads) threads = DEFAULT_THREADS;
367 if (0 == shared->messages) shared->messages = DEFAULT_MESSAGES;
368 if (0 == shared->message_length) shared->message_length = DEFAULT_MESSAGESIZE;
369
370 shared->dally = PR_SecondsToInterval(dally);
371 shared->timeout = PR_SecondsToInterval(timeout);
372
373 thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*));
374
375 for (index = 0; index < threads; ++index)
376 thread[index] = PR_CreateThread(
377 PR_USER_THREAD, Connect, shared,
378 PR_PRIORITY_NORMAL, thread_scope,
379 PR_JOINABLE_THREAD, 0);
380 for (index = 0; index < threads; ++index)
381 rv = PR_JoinThread(thread[index]);
382
383 PR_DELETE(thread);
384
385 PR_fprintf(
386 PR_GetSpecialFD(PR_StandardError), "%s\n",
387 ((shared->failed) ? "FAILED" : "PASSED"));
388 exitStatus = (shared->failed) ? 1 : 0;
389 PR_DELETE(shared);
390 return exitStatus;
391}
392
393int main(int argc, char **argv)
394{
395 return (PR_VersionCheck(PR_VERSION)) ?
396 PR_Initialize(Tmocon, argc, argv, 4) : -1;
397} /* main */
398
399/* tmocon.c */
400
401
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette