nsprpub/pr/tests/nblayer.c

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

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

mercurial