VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/nblayer.c@ 89890

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

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 24.8 KB
 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "prio.h"
39#include "prmem.h"
40#include "prprf.h"
41#include "prlog.h"
42#include "prerror.h"
43#include "prnetdb.h"
44#include "prthread.h"
45
46#include "plerror.h"
47#include "plgetopt.h"
48#include "prwin16.h"
49
50#include <stdlib.h>
51#include <string.h>
52
53/*
54** Testing layering of I/O
55**
56** The layered server
57** A thread that acts as a server. It creates a TCP listener with a dummy
58** layer pushed on top. Then listens for incoming connections. Each connection
59** request for connection will be layered as well, accept one request, echo
60** it back and close.
61**
62** The layered client
63** Pretty much what you'd expect.
64*/
65
66static PRFileDesc *logFile;
67static PRDescIdentity identity;
68static PRNetAddr server_address;
69
70static PRIOMethods myMethods;
71
72typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;
73typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;
74
75struct PRFilePrivate
76{
77 RcvState rcvstate;
78 XmtState xmtstate;
79 PRInt32 rcvreq, rcvinprogress;
80 PRInt32 xmtreq, xmtinprogress;
81};
82
83typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
84
85static PRIntn minor_iterations = 5;
86static PRIntn major_iterations = 1;
87static Verbosity verbosity = quiet;
88static PRUint16 default_port = 12273;
89
90static PRFileDesc *PushLayer(PRFileDesc *stack)
91{
92 PRStatus rv;
93 PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
94 layer->secret = PR_NEWZAP(PRFilePrivate);
95 rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
96 PR_ASSERT(PR_SUCCESS == rv);
97 if (verbosity > quiet)
98 PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
99 return stack;
100} /* PushLayer */
101
102static PRFileDesc *PopLayer(PRFileDesc *stack)
103{
104 PRFileDesc *popped = PR_PopIOLayer(stack, identity);
105 if (verbosity > quiet)
106 PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
107 PR_DELETE(popped->secret);
108 popped->dtor(popped);
109 return stack;
110} /* PopLayer */
111
112static void PR_CALLBACK Client(void *arg)
113{
114 PRStatus rv;
115 PRIntn mits;
116 PRInt32 ready;
117 PRUint8 buffer[100];
118 PRPollDesc polldesc;
119 PRIntn empty_flags = 0;
120 PRIntn bytes_read, bytes_sent;
121 PRFileDesc *stack = (PRFileDesc*)arg;
122
123 /* Initialize the buffer so that Purify won't complain */
124 memset(buffer, 0, sizeof(buffer));
125
126 rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
127 if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
128 {
129 if (verbosity > quiet)
130 PR_fprintf(logFile, "Client connect 'in progress'\n");
131 do
132 {
133 polldesc.fd = stack;
134 polldesc.out_flags = 0;
135 polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
136 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
137 if ((1 != ready) /* if not 1, then we're dead */
138 || (0 == (polldesc.in_flags & polldesc.out_flags)))
139 { PR_ASSERT(!"Whoa!"); break; }
140 if (verbosity > quiet)
141 PR_fprintf(
142 logFile, "Client connect 'in progress' [0x%x]\n",
143 polldesc.out_flags);
144 rv = PR_GetConnectStatus(&polldesc);
145 if ((PR_FAILURE == rv)
146 && (PR_IN_PROGRESS_ERROR != PR_GetError())) break;
147 } while (PR_FAILURE == rv);
148 }
149 PR_ASSERT(PR_SUCCESS == rv);
150 if (verbosity > chatty)
151 PR_fprintf(logFile, "Client created connection\n");
152
153 for (mits = 0; mits < minor_iterations; ++mits)
154 {
155 bytes_sent = 0;
156 if (verbosity > quiet)
157 PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
158 do
159 {
160 if (verbosity > chatty)
161 PR_fprintf(
162 logFile, "Client sending %d bytes\n",
163 sizeof(buffer) - bytes_sent);
164 ready = PR_Send(
165 stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,
166 empty_flags, PR_INTERVAL_NO_TIMEOUT);
167 if (verbosity > chatty)
168 PR_fprintf(logFile, "Client send status [%d]\n", ready);
169 if (0 < ready) bytes_sent += ready;
170 else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
171 {
172 polldesc.fd = stack;
173 polldesc.out_flags = 0;
174 polldesc.in_flags = PR_POLL_WRITE;
175 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
176 if ((1 != ready) /* if not 1, then we're dead */
177 || (0 == (polldesc.in_flags & polldesc.out_flags)))
178 { PR_ASSERT(!"Whoa!"); break; }
179 }
180 else break;
181 } while (bytes_sent < sizeof(buffer));
182 PR_ASSERT(sizeof(buffer) == bytes_sent);
183
184 bytes_read = 0;
185 do
186 {
187 if (verbosity > chatty)
188 PR_fprintf(
189 logFile, "Client receiving %d bytes\n",
190 bytes_sent - bytes_read);
191 ready = PR_Recv(
192 stack, buffer + bytes_read, bytes_sent - bytes_read,
193 empty_flags, PR_INTERVAL_NO_TIMEOUT);
194 if (verbosity > chatty)
195 PR_fprintf(
196 logFile, "Client receive status [%d]\n", ready);
197 if (0 < ready) bytes_read += ready;
198 else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
199 {
200 polldesc.fd = stack;
201 polldesc.out_flags = 0;
202 polldesc.in_flags = PR_POLL_READ;
203 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
204 if ((1 != ready) /* if not 1, then we're dead */
205 || (0 == (polldesc.in_flags & polldesc.out_flags)))
206 { PR_ASSERT(!"Whoa!"); break; }
207 }
208 else break;
209 } while (bytes_read < bytes_sent);
210 if (verbosity > chatty)
211 PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);
212 PR_ASSERT(bytes_read == bytes_sent);
213 }
214
215 if (verbosity > quiet)
216 PR_fprintf(logFile, "Client shutting down stack\n");
217
218 rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
219} /* Client */
220
221static void PR_CALLBACK Server(void *arg)
222{
223 PRStatus rv;
224 PRInt32 ready;
225 PRUint8 buffer[100];
226 PRFileDesc *service;
227 PRUintn empty_flags = 0;
228 struct PRPollDesc polldesc;
229 PRIntn bytes_read, bytes_sent;
230 PRFileDesc *stack = (PRFileDesc*)arg;
231 PRNetAddr client_address;
232
233 do
234 {
235 if (verbosity > chatty)
236 PR_fprintf(logFile, "Server accepting connection\n");
237 service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
238 if (verbosity > chatty)
239 PR_fprintf(logFile, "Server accept status [0x%p]\n", service);
240 if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
241 {
242 polldesc.fd = stack;
243 polldesc.out_flags = 0;
244 polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
245 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
246 if ((1 != ready) /* if not 1, then we're dead */
247 || (0 == (polldesc.in_flags & polldesc.out_flags)))
248 { PR_ASSERT(!"Whoa!"); break; }
249 }
250 } while (NULL == service);
251 PR_ASSERT(NULL != service);
252
253 if (verbosity > quiet)
254 PR_fprintf(logFile, "Server accepting connection\n");
255
256 do
257 {
258 bytes_read = 0;
259 do
260 {
261 if (verbosity > chatty)
262 PR_fprintf(
263 logFile, "Server receiving %d bytes\n",
264 sizeof(buffer) - bytes_read);
265 ready = PR_Recv(
266 service, buffer + bytes_read, sizeof(buffer) - bytes_read,
267 empty_flags, PR_INTERVAL_NO_TIMEOUT);
268 if (verbosity > chatty)
269 PR_fprintf(logFile, "Server receive status [%d]\n", ready);
270 if (0 < ready) bytes_read += ready;
271 else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
272 {
273 polldesc.fd = service;
274 polldesc.out_flags = 0;
275 polldesc.in_flags = PR_POLL_READ;
276 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
277 if ((1 != ready) /* if not 1, then we're dead */
278 || (0 == (polldesc.in_flags & polldesc.out_flags)))
279 { PR_ASSERT(!"Whoa!"); break; }
280 }
281 else break;
282 } while (bytes_read < sizeof(buffer));
283
284 if (0 != bytes_read)
285 {
286 if (verbosity > chatty)
287 PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);
288 PR_ASSERT(bytes_read > 0);
289
290 bytes_sent = 0;
291 do
292 {
293 ready = PR_Send(
294 service, buffer + bytes_sent, bytes_read - bytes_sent,
295 empty_flags, PR_INTERVAL_NO_TIMEOUT);
296 if (0 < ready)
297 {
298 bytes_sent += ready;
299 }
300 else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
301 {
302 polldesc.fd = service;
303 polldesc.out_flags = 0;
304 polldesc.in_flags = PR_POLL_WRITE;
305 ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
306 if ((1 != ready) /* if not 1, then we're dead */
307 || (0 == (polldesc.in_flags & polldesc.out_flags)))
308 { PR_ASSERT(!"Whoa!"); break; }
309 }
310 else break;
311 } while (bytes_sent < bytes_read);
312 PR_ASSERT(bytes_read == bytes_sent);
313 if (verbosity > chatty)
314 PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent);
315 }
316 } while (0 != bytes_read);
317
318 if (verbosity > quiet)
319 PR_fprintf(logFile, "Server shutting down stack\n");
320 rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
321 rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
322
323} /* Server */
324
325static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
326{
327 PR_DELETE(fd->secret); /* manage my secret file object */
328 return (PR_GetDefaultIOMethods())->close(fd); /* let him do all the work */
329} /* MyClose */
330
331static PRInt16 PR_CALLBACK MyPoll(
332 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
333{
334 PRInt16 my_flags, new_flags;
335 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
336 if (0 != (PR_POLL_READ & in_flags))
337 {
338 /* client thinks he's reading */
339 switch (mine->rcvstate)
340 {
341 case rcv_send_credit:
342 my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;
343 break;
344 case rcv_data:
345 case rcv_get_debit:
346 my_flags = in_flags;
347 default: break;
348 }
349 }
350 else if (0 != (PR_POLL_WRITE & in_flags))
351 {
352 /* client thinks he's writing */
353 switch (mine->xmtstate)
354 {
355 case xmt_recv_credit:
356 my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;
357 break;
358 case xmt_send_debit:
359 case xmt_data:
360 my_flags = in_flags;
361 default: break;
362 }
363 }
364 else PR_ASSERT(!"How'd I get here?");
365 new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);
366 if (verbosity > chatty)
367 PR_fprintf(
368 logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",
369 in_flags, my_flags, *out_flags, new_flags);
370 return new_flags;
371} /* MyPoll */
372
373static PRFileDesc * PR_CALLBACK MyAccept(
374 PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
375{
376 PRStatus rv;
377 PRFileDesc *newfd, *layer = fd;
378 PRFileDesc *newstack;
379 PRFilePrivate *newsecret;
380
381 PR_ASSERT(fd != NULL);
382 PR_ASSERT(fd->lower != NULL);
383
384 newstack = PR_NEW(PRFileDesc);
385 if (NULL == newstack)
386 {
387 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
388 return NULL;
389 }
390 newsecret = PR_NEW(PRFilePrivate);
391 if (NULL == newsecret)
392 {
393 PR_DELETE(newstack);
394 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
395 return NULL;
396 }
397 *newstack = *fd; /* make a copy of the accepting layer */
398 *newsecret = *fd->secret;
399 newstack->secret = newsecret;
400
401 newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
402 if (NULL == newfd)
403 {
404 PR_DELETE(newsecret);
405 PR_DELETE(newstack);
406 return NULL;
407 }
408
409 /* this PR_PushIOLayer call cannot fail */
410 rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
411 PR_ASSERT(PR_SUCCESS == rv);
412 return newfd; /* that's it */
413}
414
415static PRInt32 PR_CALLBACK MyRecv(
416 PRFileDesc *fd, void *buf, PRInt32 amount,
417 PRIntn flags, PRIntervalTime timeout)
418{
419 char *b;
420 PRInt32 rv;
421 PRFileDesc *lo = fd->lower;
422 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
423
424 do
425 {
426 switch (mine->rcvstate)
427 {
428 case rcv_get_debit:
429 b = (char*)&mine->rcvreq;
430 mine->rcvreq = amount;
431 rv = lo->methods->recv(
432 lo, b + mine->rcvinprogress,
433 sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
434 if (0 == rv) goto closed;
435 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
436 mine->rcvinprogress += rv; /* accumulate the read */
437 if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */
438 mine->rcvstate = rcv_send_credit;
439 mine->rcvinprogress = 0;
440 case rcv_send_credit:
441 b = (char*)&mine->rcvreq;
442 rv = lo->methods->send(
443 lo, b + mine->rcvinprogress,
444 sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
445 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
446 mine->rcvinprogress += rv; /* accumulate the read */
447 if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */
448 mine->rcvstate = rcv_data;
449 mine->rcvinprogress = 0;
450 case rcv_data:
451 b = (char*)buf;
452 rv = lo->methods->recv(
453 lo, b + mine->rcvinprogress,
454 mine->rcvreq - mine->rcvinprogress, flags, timeout);
455 if (0 == rv) goto closed;
456 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
457 mine->rcvinprogress += rv; /* accumulate the read */
458 if (mine->rcvinprogress < amount) break; /* loop */
459 mine->rcvstate = rcv_get_debit;
460 mine->rcvinprogress = 0;
461 return mine->rcvreq; /* << -- that's it! */
462 default:
463 break;
464 }
465 } while (-1 != rv);
466 return rv;
467closed:
468 mine->rcvinprogress = 0;
469 mine->rcvstate = rcv_get_debit;
470 return 0;
471} /* MyRecv */
472
473static PRInt32 PR_CALLBACK MySend(
474 PRFileDesc *fd, const void *buf, PRInt32 amount,
475 PRIntn flags, PRIntervalTime timeout)
476{
477 char *b;
478 PRInt32 rv;
479 PRFileDesc *lo = fd->lower;
480 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
481
482 do
483 {
484 switch (mine->xmtstate)
485 {
486 case xmt_send_debit:
487 b = (char*)&mine->xmtreq;
488 mine->xmtreq = amount;
489 rv = lo->methods->send(
490 lo, b - mine->xmtinprogress,
491 sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
492 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
493 mine->xmtinprogress += rv;
494 if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
495 mine->xmtstate = xmt_recv_credit;
496 mine->xmtinprogress = 0;
497 case xmt_recv_credit:
498 b = (char*)&mine->xmtreq;
499 rv = lo->methods->recv(
500 lo, b + mine->xmtinprogress,
501 sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
502 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
503 mine->xmtinprogress += rv;
504 if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
505 mine->xmtstate = xmt_data;
506 mine->xmtinprogress = 0;
507 case xmt_data:
508 b = (char*)buf;
509 rv = lo->methods->send(
510 lo, b + mine->xmtinprogress,
511 mine->xmtreq - mine->xmtinprogress, flags, timeout);
512 if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
513 mine->xmtinprogress += rv;
514 if (mine->xmtinprogress < amount) break;
515 mine->xmtstate = xmt_send_debit;
516 mine->xmtinprogress = 0;
517 return mine->xmtreq; /* <<-- That's the one! */
518 default:
519 break;
520 }
521 } while (-1 != rv);
522 return rv;
523} /* MySend */
524
525static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
526{
527 PRIntn verbage = (PRIntn)verbosity + delta;
528 if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
529 else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
530 return (Verbosity)verbage;
531} /* ChangeVerbosity */
532
533PRIntn main(PRIntn argc, char **argv)
534{
535 PRStatus rv;
536 PLOptStatus os;
537 PRFileDesc *client, *service;
538 PRNetAddr any_address;
539 const char *server_name = NULL;
540 const PRIOMethods *stubMethods;
541 PRThread *client_thread, *server_thread;
542 PRThreadScope thread_scope = PR_LOCAL_THREAD;
543 PRSocketOptionData socket_noblock, socket_nodelay;
544 PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
545 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
546 {
547 if (PL_OPT_BAD == os) continue;
548 switch (opt->option)
549 {
550 case 0:
551 server_name = opt->value;
552 break;
553 case 'd': /* debug mode */
554 if (verbosity < noisy)
555 verbosity = ChangeVerbosity(verbosity, 1);
556 break;
557 case 'q': /* debug mode */
558 if (verbosity > silent)
559 verbosity = ChangeVerbosity(verbosity, -1);
560 break;
561 case 'G': /* use global threads */
562 thread_scope = PR_GLOBAL_THREAD;
563 break;
564 case 'C': /* number of threads waiting */
565 major_iterations = atoi(opt->value);
566 break;
567 case 'c': /* number of client threads */
568 minor_iterations = atoi(opt->value);
569 break;
570 case 'p': /* default port */
571 default_port = atoi(opt->value);
572 break;
573 default:
574 break;
575 }
576 }
577 PL_DestroyOptState(opt);
578 PR_STDIO_INIT();
579
580 logFile = PR_GetSpecialFD(PR_StandardError);
581 identity = PR_GetUniqueIdentity("Dummy");
582 stubMethods = PR_GetDefaultIOMethods();
583
584 /*
585 ** The protocol we're going to implement is one where in order to initiate
586 ** a send, the sender must first solicit permission. Therefore, every
587 ** send is really a send - receive - send sequence.
588 */
589 myMethods = *stubMethods; /* first get the entire batch */
590 myMethods.accept = MyAccept; /* then override the ones we care about */
591 myMethods.recv = MyRecv; /* then override the ones we care about */
592 myMethods.send = MySend; /* then override the ones we care about */
593 myMethods.close = MyClose; /* then override the ones we care about */
594 myMethods.poll = MyPoll; /* then override the ones we care about */
595
596 if (NULL == server_name)
597 rv = PR_InitializeNetAddr(
598 PR_IpAddrLoopback, default_port, &server_address);
599 else
600 {
601 rv = PR_StringToNetAddr(server_name, &server_address);
602 PR_ASSERT(PR_SUCCESS == rv);
603 rv = PR_InitializeNetAddr(
604 PR_IpAddrNull, default_port, &server_address);
605 }
606 PR_ASSERT(PR_SUCCESS == rv);
607
608 socket_noblock.value.non_blocking = PR_TRUE;
609 socket_noblock.option = PR_SockOpt_Nonblocking;
610 socket_nodelay.value.no_delay = PR_TRUE;
611 socket_nodelay.option = PR_SockOpt_NoDelay;
612
613 /* one type w/o layering */
614
615 while (major_iterations-- > 0)
616 {
617 if (verbosity > silent)
618 PR_fprintf(logFile, "Beginning non-layered test\n");
619
620 client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
621 service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
622
623 rv = PR_SetSocketOption(client, &socket_noblock);
624 PR_ASSERT(PR_SUCCESS == rv);
625 rv = PR_SetSocketOption(service, &socket_noblock);
626 PR_ASSERT(PR_SUCCESS == rv);
627 rv = PR_SetSocketOption(client, &socket_nodelay);
628 PR_ASSERT(PR_SUCCESS == rv);
629 rv = PR_SetSocketOption(service, &socket_nodelay);
630 PR_ASSERT(PR_SUCCESS == rv);
631
632 rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
633 PR_ASSERT(PR_SUCCESS == rv);
634 rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
635 rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
636
637 server_thread = PR_CreateThread(
638 PR_USER_THREAD, Server, service,
639 PR_PRIORITY_HIGH, thread_scope,
640 PR_JOINABLE_THREAD, 16 * 1024);
641 PR_ASSERT(NULL != server_thread);
642
643 client_thread = PR_CreateThread(
644 PR_USER_THREAD, Client, client,
645 PR_PRIORITY_NORMAL, thread_scope,
646 PR_JOINABLE_THREAD, 16 * 1024);
647 PR_ASSERT(NULL != client_thread);
648
649 rv = PR_JoinThread(client_thread);
650 PR_ASSERT(PR_SUCCESS == rv);
651 rv = PR_JoinThread(server_thread);
652 PR_ASSERT(PR_SUCCESS == rv);
653
654 rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
655 rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
656 if (verbosity > silent)
657 PR_fprintf(logFile, "Ending non-layered test\n");
658
659 /* with layering */
660 if (verbosity > silent)
661 PR_fprintf(logFile, "Beginning layered test\n");
662 client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
663 service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
664
665 rv = PR_SetSocketOption(client, &socket_noblock);
666 PR_ASSERT(PR_SUCCESS == rv);
667 rv = PR_SetSocketOption(service, &socket_noblock);
668 PR_ASSERT(PR_SUCCESS == rv);
669 rv = PR_SetSocketOption(client, &socket_nodelay);
670 PR_ASSERT(PR_SUCCESS == rv);
671 rv = PR_SetSocketOption(service, &socket_nodelay);
672 PR_ASSERT(PR_SUCCESS == rv);
673
674 PushLayer(client);
675 PushLayer(service);
676
677 rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
678 PR_ASSERT(PR_SUCCESS == rv);
679 rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
680 rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
681
682 server_thread = PR_CreateThread(
683 PR_USER_THREAD, Server, service,
684 PR_PRIORITY_HIGH, thread_scope,
685 PR_JOINABLE_THREAD, 16 * 1024);
686 PR_ASSERT(NULL != server_thread);
687
688 client_thread = PR_CreateThread(
689 PR_USER_THREAD, Client, client,
690 PR_PRIORITY_NORMAL, thread_scope,
691 PR_JOINABLE_THREAD, 16 * 1024);
692 PR_ASSERT(NULL != client_thread);
693
694 rv = PR_JoinThread(client_thread);
695 PR_ASSERT(PR_SUCCESS == rv);
696 rv = PR_JoinThread(server_thread);
697 PR_ASSERT(PR_SUCCESS == rv);
698
699 rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv);
700 rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv);
701 if (verbosity > silent)
702 PR_fprintf(logFile, "Ending layered test\n");
703 }
704 return 0;
705} /* main */
706
707/* nblayer.c */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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