Added new test files. NSPRPUB_19980508_BASE
authorwtc
Fri, 08 May 1998 23:07:27 +0000
changeset 113 d3fcb11168db042ba3307dfe50b86932efc44c9f
parent 112 b720c8244ce62cd97758c3ef5f5b0e8a6b854845
child 114 ed63234acf412516e1b54518041cbdac8b1d7fd1
child 116 46d9c404877a263b69ed6db17617acf45b071ff6
push idunknown
push userunknown
push dateunknown
Added new test files.
pr/tests/dtoa.c
pr/tests/nblayer.c
pr/tests/short_thread.c
pr/tests/testbit.c
new file mode 100644
--- /dev/null
+++ b/pr/tests/dtoa.c
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+/******************************************************************************
+ *
+ * This file contains a test program for the function conversion functions
+ * for double precision code:
+ * PR_strtod
+ * PR_dtoa
+ * PR_cnvtf
+ *
+ * This file was ns/nspr/tests/dtoa.c, created by rrj on 1996/06/22.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <locale.h>
+#include "prprf.h"
+#include "prdtoa.h"
+
+static int failed_already = 0;
+
+int main( int argc, char* argv[] )
+{
+    double num;
+    double num1;
+    double zero = 0.0;
+    char   cnvt[50];
+    
+    num = 1e24;
+    num1 = PR_strtod("1e24",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1e24");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1e+24",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.001e7;
+    num1 = PR_strtod("0.001e7",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","0.001e7");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("10000",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.0000000000000753;
+    num1 = PR_strtod("0.0000000000000753",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"0.0000000000000753");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("7.53e-14",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.867e73;
+    num1 = PR_strtod("1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+
+    num = -1.867e73;
+    num1 = PR_strtod("-1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.867e-73;
+    num1 = PR_strtod("-1.867e-73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e-73");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e-73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for infinity */
+    num = 1.0 / zero;
+    num1 = PR_strtod("1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.0 / zero;
+    num1 = PR_strtod("-1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for NaN. PR_strtod can't parse "NaN" and "Infinity" */
+    num = zero / zero;
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = - zero / zero;
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.0000000001e21;
+    num1 = PR_strtod("1.0000000001e21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"1.0000000001e21");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.0000000001e+21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+
+    num = -1.0000000001e-21;
+    num1 = PR_strtod("-1.0000000001e-21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"-1.0000000001e-21");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.0000000001e-21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+    if (failed_already) {
+        printf("FAILED\n");
+    } else {
+        printf("PASSED\n");
+    }
+    return failed_already;
+}
new file mode 100644
--- /dev/null
+++ b/pr/tests/nblayer.c
@@ -0,0 +1,606 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "prwin16.h"
+
+#include <stdlib.h>
+
+/*
+** Testing layering of I/O
+**
+**      The layered server
+** A thread that acts as a server. It creates a TCP listener with a dummy
+** layer pushed on top. Then listens for incoming connections. Each connection
+** request for connection will be layered as well, accept one request, echo
+** it back and close.
+**
+**      The layered client
+** Pretty much what you'd expect.
+*/
+
+static PRFileDesc *logFile;
+static PRDescIdentity identity;
+static PRNetAddr server_address;
+
+static PRIOMethods myMethods;
+
+typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;
+typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;
+
+struct PRFilePrivate
+{
+    RcvState rcvstate;
+    XmtState xmtstate;
+    PRInt32 rcvreq, rcvinprogress;
+    PRInt32 xmtreq, xmtinprogress;
+};
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRIntn minor_iterations = 5;
+static PRIntn major_iterations = 1;
+static Verbosity verbosity = quiet;
+static PRUint16 default_port = 12273;
+
+static PRFileDesc *PushLayer(PRFileDesc *stack)
+{
+    PRStatus rv;
+    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
+    layer->secret = PR_NEWZAP(PRFilePrivate);
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
+    return stack;
+}  /* PushLayer */
+
+static PRFileDesc *PopLayer(PRFileDesc *stack)
+{
+    PRFileDesc *popped = PR_PopIOLayer(stack, identity);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
+    PR_DELETE(popped->secret);
+    popped->dtor(popped);
+    return stack;
+}  /* PopLayer */
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn mits;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRPollDesc polldesc;
+    PRIntn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+
+    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
+    if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
+    {
+        do
+        {
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if (1 != ready) break;  /* if not 1, then we're dead */
+                rv = PR_GetConnectStatus(&polldesc);
+                if (PR_FAILURE == rv)
+                {
+                    if (PR_IN_PROGRESS_ERROR != PR_GetError()) break;
+                }
+            }
+        } while (PR_FAILURE == rv);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > chatty)
+        PR_fprintf(logFile, "Client created connection\n");
+
+    for (mits = 0; mits < minor_iterations; ++mits)
+    {
+        bytes_sent = 0;
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
+        do
+        {
+            ready = PR_Send(
+                stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (0 < ready)
+            {
+                bytes_sent += ready;
+            }
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_WRITE;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if (1 != ready) break;  /* if not 1, then we're dead */
+            }
+            else break;
+        } while (bytes_sent < sizeof(buffer));
+        PR_ASSERT(sizeof(buffer) == bytes_sent);
+
+        bytes_read = 0;
+        do
+        {
+            ready = PR_Recv(
+                stack, buffer + bytes_read, bytes_sent - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (0 < ready)
+            {
+                bytes_read += ready;
+            }
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if (1 != ready) break;  /* if not 1, then we're dead */
+            }
+            else break;
+        } while (bytes_read < bytes_sent);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);
+        PR_ASSERT(bytes_read == bytes_sent);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Client shutting down stack\n");
+    
+    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+}  /* Client */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRFileDesc *service;
+    PRUintn empty_flags = 0;
+    struct PRPollDesc polldesc;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+    PRNetAddr any_address, client_address;
+
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    rv = PR_Bind(stack, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Listen(stack, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+    do
+    {
+        service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
+        if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+        {
+            polldesc.fd = stack;
+            polldesc.out_flags = 0;
+            polldesc.in_flags = PR_POLL_READ;
+            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+            if (1 != ready) break;  /* if not 1, then we're dead */
+        }
+    } while (NULL == service);
+    PR_ASSERT(NULL != service);
+        
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server accepting connection\n");
+
+    do
+    {
+        bytes_read = 0;
+        do
+        {
+            ready = PR_Recv(
+                service, buffer + bytes_read, sizeof(buffer) - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (0 < ready)
+            {
+                bytes_read += ready;
+            }
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = service;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if (1 != ready) break;  /* if not 1, then we're dead */
+            }
+            else break;
+        } while (bytes_read < sizeof(buffer));
+
+        if (0 != bytes_read)
+        {
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);
+            PR_ASSERT(bytes_read > 0);
+
+            bytes_sent = 0;
+            do
+            {
+                ready = PR_Send(
+                    service, buffer + bytes_sent, bytes_read - bytes_sent,
+                    empty_flags, PR_INTERVAL_NO_TIMEOUT);
+                if (0 < ready)
+                {
+                    bytes_sent += ready;
+                }
+                else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+                {
+                    polldesc.fd = service;
+                    polldesc.out_flags = 0;
+                    polldesc.in_flags = PR_POLL_WRITE;
+                    ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                    if (1 != ready) break;  /* if not 1, then we're dead */
+                }
+                else break;
+            } while (bytes_sent < bytes_read);
+            PR_ASSERT(bytes_read == bytes_sent);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent);
+        }
+    } while (0 != bytes_read);
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server shutting down and closing stack\n");
+    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+
+}  /* Server */
+
+static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
+{
+    PR_DELETE(fd->secret);  /* manage my secret file object */
+    return (PR_GetDefaultIOMethods())->close(fd);  /* let him do all the work */
+}  /* MyClose */
+
+static PRInt16 PR_CALLBACK MyPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PRInt16 my_flags, new_flags;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+    if (0 != (PR_POLL_READ & in_flags))
+    {
+        /* client thinks he's reading */
+        switch (mine->rcvstate)
+        {
+            case rcv_send_credit:
+                my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;
+                break;
+            case rcv_data:
+            case rcv_get_debit:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else if (0 != (PR_POLL_WRITE & in_flags))
+    {
+        /* client thinks he's writing */
+        switch (mine->xmtstate)
+        {
+            case xmt_recv_credit:
+                my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;
+                break;
+            case xmt_send_debit:
+            case xmt_data:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else PR_ASSERT(!"How'd I get here?");
+    new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);
+    if (verbosity > chatty)
+        PR_fprintf(
+            logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",
+            in_flags, my_flags, *out_flags, new_flags);
+    return new_flags;
+}  /* MyPoll */
+
+static PRInt32 PR_CALLBACK MyRecv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRPollDesc polldesc;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->rcvstate)
+        {
+        case rcv_get_debit:
+            b = (char*)&mine->rcvreq;
+            mine->rcvreq = amount;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_send_credit;
+            mine->rcvinprogress = 0;
+        case rcv_send_credit:
+            b = (char*)&mine->rcvreq;
+            rv = lo->methods->send(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_data;
+            mine->rcvinprogress = 0;
+        case rcv_data:
+            b = (char*)buf;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                mine->rcvreq - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < amount) break;  /* loop */
+            mine->rcvstate = rcv_get_debit;
+            mine->rcvinprogress = 0;
+            return mine->rcvreq;  /* << -- that's it! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+closed:
+    mine->rcvinprogress = 0;
+    mine->rcvstate = rcv_get_debit;
+    return 0;
+}  /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->xmtstate)
+        {
+        case xmt_send_debit:
+            b = (char*)&mine->xmtreq;
+            mine->xmtreq = amount;
+            rv = lo->methods->send(
+                lo, b - mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_recv_credit;
+            mine->xmtinprogress = 0;
+        case xmt_recv_credit:
+             b = (char*)&mine->xmtreq;
+             rv = lo->methods->recv(
+                lo, b + mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_data;
+            mine->xmtinprogress = 0;
+        case xmt_data:
+            b = (char*)buf;
+            rv = lo->methods->send(
+                lo, b + mine->xmtinprogress,
+                mine->xmtreq - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < amount) break;
+            mine->xmtstate = xmt_send_debit;
+            mine->xmtinprogress = 0;
+            return mine->xmtreq;  /* <<-- That's the one! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+}  /* MySend */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity + delta;
+    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+    return (Verbosity)verbage;
+}  /* ChangeVerbosity */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRFileDesc *client, *service;
+    const char *server_name = NULL;
+    const PRIOMethods *stubMethods;
+    PRThread *client_thread, *server_thread;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRSocketOptionData socket_noblock, socket_nodelay;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            server_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'C':  /* number of threads waiting */
+            major_iterations = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            minor_iterations = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    logFile = PR_GetSpecialFD(PR_StandardError);
+    identity = PR_GetUniqueIdentity("Dummy");
+    stubMethods = PR_GetDefaultIOMethods();
+
+    /*
+    ** The protocol we're going to implement is one where in order to initiate
+    ** a send, the sender must first solicit permission. Therefore, every
+    ** send is really a send - receive - send sequence.
+    */
+    myMethods = *stubMethods;  /* first get the entire batch */
+    myMethods.recv = MyRecv;  /* then override the ones we care about */
+    myMethods.send = MySend;  /* then override the ones we care about */
+    myMethods.close = MyClose;  /* then override the ones we care about */
+    myMethods.poll = MyPoll;  /* then override the ones we care about */
+
+    if (NULL == server_name)
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, default_port, &server_address);
+    else
+    {
+        rv = PR_StringToNetAddr(server_name, &server_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrNull, default_port, &server_address);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    socket_noblock.value.non_blocking = PR_TRUE;
+    socket_noblock.option = PR_SockOpt_Nonblocking;
+    socket_nodelay.value.no_delay = PR_TRUE;
+    socket_nodelay.option = PR_SockOpt_NoDelay;
+
+    /* one type w/o layering */
+
+    while (major_iterations-- > 0)
+    {
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning non-layered test\n");
+
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending non-layered test\n");
+
+        /* with layering */
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, PushLayer(service),
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, PushLayer(client),
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending layered test\n");
+    }
+    return 0;
+}  /* main */
+
+/* layer.c */
new file mode 100644
--- /dev/null
+++ b/pr/tests/short_thread.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include <stdio.h>
+#include "nspr.h"
+#include "plgetopt.h"
+
+/*
+ * Create a thread that exits right away; useful for testing race conditions in thread
+ * creation
+ */
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+static void housecleaning(void *cur_time);
+
+int main (int argc, char **argv)
+{
+	static PRIntervalTime thread_start_time;
+	static PRThread *housekeeping_tid = NULL;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+	{
+		if (PL_OPT_BAD == os) continue;
+		switch (opt->option)
+		{
+			case 'd':  /* debug mode */
+				_debug_on = 1;
+				break;
+			default:
+				break;
+		}
+	}
+	PL_DestroyOptState(opt);
+
+	if (( housekeeping_tid = 
+		PR_CreateThread (PR_USER_THREAD, housecleaning,  (void*)&thread_start_time,
+						 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0)) 
+																		== NULL ) {
+		fprintf(stderr,
+			"simple_test: Error - PR_CreateThread failed: (%ld, %ld)\n",
+									  PR_GetError(), PR_GetOSError());
+		exit( 1 );
+	}
+	PR_Cleanup();
+	return(0);
+}
+
+static void
+housecleaning (void *cur_time) 
+{
+  DPRINTF(("Child Thread exiting\n"));
+}
new file mode 100644
--- /dev/null
+++ b/pr/tests/testbit.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+/*
+** File:        lazyinit.c
+** Description: Test the functions and macros declared in prbit.h
+**
+*/
+
+#include "nspr.h"
+
+#define ErrorReport(x) { printf((x)); failed = 1; }
+
+prbitmap_t myMap[512/32] = { 0 };
+
+PRInt32 rc;
+PRInt32 i;
+PRIntn  failed = 0;
+
+PRIntn main(PRIntn argc, char **argv )
+{
+    /*
+    ** Test bitmap things.
+    */
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 0.0: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 0.1: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 0.2: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 0.3: Failed\n");
+
+
+    PR_SET_BIT( myMap, 0 );
+    if ( !PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 0 );
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0.1: Failed\n");
+
+    PR_SET_BIT( myMap, 31 );
+    if ( !PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 31 );
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1.1: Failed\n");
+
+    PR_SET_BIT( myMap, 128 );
+    if ( !PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 128 );
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2.1: Failed\n");
+
+    PR_SET_BIT( myMap, 129 );
+    if ( !PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 129 );
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3.1: Failed\n");
+
+
+    /*
+    ** Test Ceiling and Floor functions and macros
+    */
+    if ((rc = PR_CeilingLog2(32)) != 5 )
+        ErrorReport("Test 10.0: Failed\n");
+
+    if ((rc = PR_FloorLog2(32)) != 5 )
+        ErrorReport("Test 10.1: Failed\n");
+
+
+    /*
+    ** Evaluate results and exit
+    */
+    if (failed)
+      {
+        printf("FAILED\n");
+        return(1);
+      }
+    else
+      {
+        printf("PASSED\n");
+        return(0);
+      }
+}  /* end main() */
+/* end testbit.c */