Bug 462294 - Add "View Video" to context menu for <video> elements. r=gavin, ui...
[wine-gecko.git] / nsprpub / pr / tests / nblayer.c
blob4ecc955c3e590276b12bb4be7bd457bc26252b74
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
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/
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.
15 * The Original Code is the Netscape Portable Runtime (NSPR).
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.
22 * Contributor(s):
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.
36 * ***** END LICENSE BLOCK ***** */
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"
46 #include "plerror.h"
47 #include "plgetopt.h"
48 #include "prwin16.h"
50 #include <stdlib.h>
51 #include <string.h>
54 ** Testing layering of I/O
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.
62 ** The layered client
63 ** Pretty much what you'd expect.
66 static PRFileDesc *logFile;
67 static PRDescIdentity identity;
68 static PRNetAddr server_address;
70 static PRIOMethods myMethods;
72 typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;
73 typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;
75 struct PRFilePrivate
77 RcvState rcvstate;
78 XmtState xmtstate;
79 PRInt32 rcvreq, rcvinprogress;
80 PRInt32 xmtreq, xmtinprogress;
83 typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
85 static PRIntn minor_iterations = 5;
86 static PRIntn major_iterations = 1;
87 static Verbosity verbosity = quiet;
88 static PRUint16 default_port = 12273;
90 static PRFileDesc *PushLayer(PRFileDesc *stack)
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 */
102 static PRFileDesc *PopLayer(PRFileDesc *stack)
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 */
112 static void PR_CALLBACK Client(void *arg)
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;
123 /* Initialize the buffer so that Purify won't complain */
124 memset(buffer, 0, sizeof(buffer));
126 rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
127 if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
129 if (verbosity > quiet)
130 PR_fprintf(logFile, "Client connect 'in progress'\n");
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);
149 PR_ASSERT(PR_SUCCESS == rv);
150 if (verbosity > chatty)
151 PR_fprintf(logFile, "Client created connection\n");
153 for (mits = 0; mits < minor_iterations; ++mits)
155 bytes_sent = 0;
156 if (verbosity > quiet)
157 PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
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()))
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; }
180 else break;
181 } while (bytes_sent < sizeof(buffer));
182 PR_ASSERT(sizeof(buffer) == bytes_sent);
184 bytes_read = 0;
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()))
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; }
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);
215 if (verbosity > quiet)
216 PR_fprintf(logFile, "Client shutting down stack\n");
218 rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
219 } /* Client */
221 static void PR_CALLBACK Server(void *arg)
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;
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()))
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; }
250 } while (NULL == service);
251 PR_ASSERT(NULL != service);
253 if (verbosity > quiet)
254 PR_fprintf(logFile, "Server accepting connection\n");
258 bytes_read = 0;
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()))
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; }
281 else break;
282 } while (bytes_read < sizeof(buffer));
284 if (0 != bytes_read)
286 if (verbosity > chatty)
287 PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);
288 PR_ASSERT(bytes_read > 0);
290 bytes_sent = 0;
293 ready = PR_Send(
294 service, buffer + bytes_sent, bytes_read - bytes_sent,
295 empty_flags, PR_INTERVAL_NO_TIMEOUT);
296 if (0 < ready)
298 bytes_sent += ready;
300 else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
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; }
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);
316 } while (0 != bytes_read);
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);
323 } /* Server */
325 static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
327 PR_DELETE(fd->secret); /* manage my secret file object */
328 return (PR_GetDefaultIOMethods())->close(fd); /* let him do all the work */
329 } /* MyClose */
331 static PRInt16 PR_CALLBACK MyPoll(
332 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
334 PRInt16 my_flags, new_flags;
335 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
336 if (0 != (PR_POLL_READ & in_flags))
338 /* client thinks he's reading */
339 switch (mine->rcvstate)
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;
350 else if (0 != (PR_POLL_WRITE & in_flags))
352 /* client thinks he's writing */
353 switch (mine->xmtstate)
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;
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 */
373 static PRFileDesc * PR_CALLBACK MyAccept(
374 PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
376 PRStatus rv;
377 PRFileDesc *newfd, *layer = fd;
378 PRFileDesc *newstack;
379 PRFilePrivate *newsecret;
381 PR_ASSERT(fd != NULL);
382 PR_ASSERT(fd->lower != NULL);
384 newstack = PR_NEW(PRFileDesc);
385 if (NULL == newstack)
387 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
388 return NULL;
390 newsecret = PR_NEW(PRFilePrivate);
391 if (NULL == newsecret)
393 PR_DELETE(newstack);
394 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
395 return NULL;
397 *newstack = *fd; /* make a copy of the accepting layer */
398 *newsecret = *fd->secret;
399 newstack->secret = newsecret;
401 newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
402 if (NULL == newfd)
404 PR_DELETE(newsecret);
405 PR_DELETE(newstack);
406 return NULL;
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 */
415 static PRInt32 PR_CALLBACK MyRecv(
416 PRFileDesc *fd, void *buf, PRInt32 amount,
417 PRIntn flags, PRIntervalTime timeout)
419 char *b;
420 PRInt32 rv;
421 PRFileDesc *lo = fd->lower;
422 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
426 switch (mine->rcvstate)
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;
465 } while (-1 != rv);
466 return rv;
467 closed:
468 mine->rcvinprogress = 0;
469 mine->rcvstate = rcv_get_debit;
470 return 0;
471 } /* MyRecv */
473 static PRInt32 PR_CALLBACK MySend(
474 PRFileDesc *fd, const void *buf, PRInt32 amount,
475 PRIntn flags, PRIntervalTime timeout)
477 char *b;
478 PRInt32 rv;
479 PRFileDesc *lo = fd->lower;
480 PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
484 switch (mine->xmtstate)
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;
521 } while (-1 != rv);
522 return rv;
523 } /* MySend */
525 static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
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 */
533 PRIntn main(PRIntn argc, char **argv)
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)))
547 if (PL_OPT_BAD == os) continue;
548 switch (opt->option)
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;
577 PL_DestroyOptState(opt);
578 PR_STDIO_INIT();
580 logFile = PR_GetSpecialFD(PR_StandardError);
581 identity = PR_GetUniqueIdentity("Dummy");
582 stubMethods = PR_GetDefaultIOMethods();
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.
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 */
596 if (NULL == server_name)
597 rv = PR_InitializeNetAddr(
598 PR_IpAddrLoopback, default_port, &server_address);
599 else
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);
606 PR_ASSERT(PR_SUCCESS == rv);
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;
613 /* one type w/o layering */
615 while (major_iterations-- > 0)
617 if (verbosity > silent)
618 PR_fprintf(logFile, "Beginning non-layered test\n");
620 client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
621 service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
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);
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);
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);
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);
649 rv = PR_JoinThread(client_thread);
650 PR_ASSERT(PR_SUCCESS == rv);
651 rv = PR_JoinThread(server_thread);
652 PR_ASSERT(PR_SUCCESS == rv);
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");
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);
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);
674 PushLayer(client);
675 PushLayer(service);
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);
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);
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);
694 rv = PR_JoinThread(client_thread);
695 PR_ASSERT(PR_SUCCESS == rv);
696 rv = PR_JoinThread(server_thread);
697 PR_ASSERT(PR_SUCCESS == rv);
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");
704 return 0;
705 } /* main */
707 /* nblayer.c */