nsprpub/pr/tests/nonblock.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/tests/nonblock.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,225 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nspr.h"
    1.10 +#include "prio.h"
    1.11 +#include "prerror.h"
    1.12 +#include "prlog.h"
    1.13 +#include "prprf.h"
    1.14 +#include "prnetdb.h"
    1.15 +#include "plerror.h"
    1.16 +#include "obsolete/probslet.h"
    1.17 +
    1.18 +#include <stdio.h>
    1.19 +#include <string.h>
    1.20 +#include <stdlib.h>
    1.21 +
    1.22 +#define NUMBER_ROUNDS 5
    1.23 +
    1.24 +#if defined(WIN16)
    1.25 +/*
    1.26 +** Make win16 unit_time interval 300 milliseconds, others get 100
    1.27 +*/
    1.28 +#define UNIT_TIME  200       /* unit time in milliseconds */
    1.29 +#elif defined(SYMBIAN)
    1.30 +#define UNIT_TIME  5000      /* unit time in milliseconds */
    1.31 +#else
    1.32 +#define UNIT_TIME  100       /* unit time in milliseconds */
    1.33 +#endif
    1.34 +#define CHUNK_SIZE 10
    1.35 +#undef USE_PR_SELECT         /* If defined, we use PR_Select.
    1.36 +                              * If not defined, use PR_Poll instead. */
    1.37 +
    1.38 +#if defined(USE_PR_SELECT)
    1.39 +#include "pprio.h"
    1.40 +#endif
    1.41 +
    1.42 +static void PR_CALLBACK
    1.43 +clientThreadFunc(void *arg)
    1.44 +{
    1.45 +    PRUintn port = (PRUintn)arg;
    1.46 +    PRFileDesc *sock;
    1.47 +    PRNetAddr addr;
    1.48 +    char buf[CHUNK_SIZE];
    1.49 +    int i;
    1.50 +    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
    1.51 +    PRSocketOptionData optval;
    1.52 +    PRStatus retVal;
    1.53 +    PRInt32 nBytes;
    1.54 +
    1.55 +    /* Initialize the buffer so that Purify won't complain */
    1.56 +    memset(buf, 0, sizeof(buf));
    1.57 +
    1.58 +    addr.inet.family = PR_AF_INET;
    1.59 +    addr.inet.port = PR_htons((PRUint16)port);
    1.60 +    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    1.61 +    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
    1.62 +
    1.63 +    /* time 1 */
    1.64 +    PR_Sleep(unitTime);
    1.65 +    sock = PR_NewTCPSocket();
    1.66 +    optval.option = PR_SockOpt_Nonblocking;
    1.67 +    optval.value.non_blocking = PR_TRUE;
    1.68 +    PR_SetSocketOption(sock, &optval);
    1.69 +    retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
    1.70 +    if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
    1.71 +#if !defined(USE_PR_SELECT)
    1.72 +	PRPollDesc pd;
    1.73 +	PRInt32 n;
    1.74 +	fprintf(stderr, "connect: EWOULDBLOCK, good\n");
    1.75 +	pd.fd = sock;
    1.76 +	pd.in_flags = PR_POLL_WRITE;
    1.77 +	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
    1.78 +	PR_ASSERT(n == 1);
    1.79 +        PR_ASSERT(pd.out_flags == PR_POLL_WRITE);
    1.80 +#else
    1.81 +        PR_fd_set writeSet;
    1.82 +        PRInt32 n;
    1.83 +        fprintf(stderr, "connect: EWOULDBLOCK, good\n");
    1.84 +        PR_FD_ZERO(&writeSet);
    1.85 +        PR_FD_SET(sock, &writeSet);
    1.86 +        n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT);
    1.87 +        PR_ASSERT(n == 1);
    1.88 +        PR_ASSERT(PR_FD_ISSET(sock, &writeSet));
    1.89 +#endif
    1.90 +    }
    1.91 +    printf("client connected\n");
    1.92 +    fflush(stdout);
    1.93 +
    1.94 +    /* time 4, 7, 11, etc. */
    1.95 +    for (i = 0; i < NUMBER_ROUNDS; i++) {
    1.96 +        PR_Sleep(3 * unitTime);
    1.97 +    	nBytes = PR_Write(sock, buf, sizeof(buf));
    1.98 +	    if (nBytes == -1) {
    1.99 +	    if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
   1.100 +		fprintf(stderr, "write: EWOULDBLOCK\n");
   1.101 +		exit(1);
   1.102 +            } else {
   1.103 +		fprintf(stderr, "write: failed\n");
   1.104 +            }
   1.105 +	}
   1.106 +	printf("client sent %d bytes\n", nBytes);
   1.107 +	fflush(stdout);
   1.108 +    }
   1.109 +
   1.110 +    PR_Close(sock);
   1.111 +}
   1.112 +
   1.113 +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
   1.114 +{
   1.115 +    PRFileDesc *listenSock, *sock;
   1.116 +    PRUint16 listenPort;
   1.117 +    PRNetAddr addr;
   1.118 +    char buf[CHUNK_SIZE];
   1.119 +    PRThread *clientThread;
   1.120 +    PRInt32 retVal;
   1.121 +    PRSocketOptionData optval;
   1.122 +    PRIntn i;
   1.123 +    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
   1.124 +
   1.125 +    /* Create a listening socket */
   1.126 +    if ((listenSock = PR_NewTCPSocket()) == NULL) {
   1.127 +	fprintf(stderr, "Can't create a new TCP socket\n");
   1.128 +	exit(1);
   1.129 +    }
   1.130 +    addr.inet.family = PR_AF_INET;
   1.131 +    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
   1.132 +    addr.inet.port = PR_htons(0);
   1.133 +    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
   1.134 +	fprintf(stderr, "Can't bind socket\n");
   1.135 +	exit(1);
   1.136 +    }
   1.137 +    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
   1.138 +	fprintf(stderr, "PR_GetSockName failed\n");
   1.139 +	exit(1);
   1.140 +    }
   1.141 +    listenPort = PR_ntohs(addr.inet.port);
   1.142 +    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
   1.143 +	fprintf(stderr, "Can't listen on a socket\n");
   1.144 +	exit(1);
   1.145 +    }
   1.146 +
   1.147 +    PR_snprintf(buf, sizeof(buf),
   1.148 +	    "The server thread is listening on port %hu\n\n",
   1.149 +	    listenPort);
   1.150 +    printf("%s", buf);
   1.151 +
   1.152 +    clientThread = PR_CreateThread(PR_USER_THREAD,
   1.153 +	    clientThreadFunc, (void *) listenPort,
   1.154 +	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
   1.155 +	    PR_UNJOINABLE_THREAD, 0);
   1.156 +    if (clientThread == NULL) {
   1.157 +	fprintf(stderr, "can't create thread\n");
   1.158 +	exit(1);
   1.159 +    }
   1.160 +
   1.161 +    printf("client thread created.\n");
   1.162 +
   1.163 +    optval.option = PR_SockOpt_Nonblocking;
   1.164 +    optval.value.non_blocking = PR_TRUE;
   1.165 +    PR_SetSocketOption(listenSock, &optval);
   1.166 +    /* time 0 */
   1.167 +    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
   1.168 +    if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
   1.169 +        PL_PrintError("First Accept\n");
   1.170 +        fprintf(stderr, "First PR_Accept() xxx\n" );
   1.171 +		    exit(1);
   1.172 +    }
   1.173 +    printf("accept: EWOULDBLOCK, good\n");
   1.174 +    fflush(stdout);
   1.175 +    /* time 2 */
   1.176 +    PR_Sleep(2 * unitTime);
   1.177 +    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
   1.178 +    if (sock == NULL) {
   1.179 +        PL_PrintError("Second Accept\n");
   1.180 +        fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n",
   1.181 +                PR_GetError(), PR_GetOSError());
   1.182 +		    exit(1);
   1.183 +    }
   1.184 +    printf("accept: succeeded, good\n");
   1.185 +    fflush(stdout);
   1.186 +    PR_Close(listenSock);
   1.187 +
   1.188 +    PR_SetSocketOption(sock, &optval);
   1.189 +
   1.190 +    /* time 3, 5, 6, 8, etc. */
   1.191 +    for (i = 0; i < NUMBER_ROUNDS; i++) {
   1.192 +	PR_Sleep(unitTime);
   1.193 +	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
   1.194 +	if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
   1.195 +        PL_PrintError("First Receive:\n");
   1.196 +	    fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n",
   1.197 +            retVal, PR_GetError());
   1.198 +	    exit(1);
   1.199 +        }
   1.200 +	printf("read: EWOULDBLOCK, good\n");
   1.201 +	fflush(stdout);
   1.202 +	PR_Sleep(2 * unitTime);
   1.203 +	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
   1.204 +	if (retVal != CHUNK_SIZE) {
   1.205 +        PL_PrintError("Second Receive:\n");
   1.206 +	    fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", 
   1.207 +            retVal, PR_GetError());
   1.208 +	    exit(1);
   1.209 +        }
   1.210 +	printf("read: %d bytes, good\n", retVal);
   1.211 +	fflush(stdout);
   1.212 +    }
   1.213 +    PR_Close(sock);
   1.214 +
   1.215 +    printf("All tests finished\n");
   1.216 +    printf("PASS\n");
   1.217 +    return 0;
   1.218 +}
   1.219 +
   1.220 +int main(int argc, char **argv)
   1.221 +{
   1.222 +    PRIntn rv;
   1.223 +    
   1.224 +    PR_STDIO_INIT();
   1.225 +    rv = PR_Initialize(RealMain, argc, argv, 0);
   1.226 +    return rv;
   1.227 +}  /* main */
   1.228 +

mercurial