nsprpub/pr/tests/multiacc.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 /*
     7  * File: multiacc.c
     8  *
     9  * Description:
    10  * This test creates multiple threads that accept on the
    11  * same listening socket.
    12  */
    14 #include "nspr.h"
    16 #include <stdio.h>
    17 #include <stdlib.h>
    18 #include <string.h>
    20 #define NUM_SERVER_THREADS 10
    22 static int num_server_threads = NUM_SERVER_THREADS;
    23 static PRThreadScope thread_scope = PR_GLOBAL_THREAD;
    24 static PRBool exit_flag = PR_FALSE;
    26 static void ServerThreadFunc(void *arg)
    27 {
    28     PRFileDesc *listenSock = (PRFileDesc *) arg;
    29     PRFileDesc *acceptSock;
    30     PRErrorCode err;
    31     PRStatus status;
    33     while (!exit_flag) {
    34         acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
    35         if (NULL == acceptSock) {
    36             err = PR_GetError();
    37             if (PR_PENDING_INTERRUPT_ERROR == err) {
    38                 printf("server thread is interrupted\n");
    39                 fflush(stdout);
    40                 continue;
    41             }
    42             fprintf(stderr, "PR_Accept failed: %d\n", err);
    43             exit(1);
    44         }
    45         status = PR_Close(acceptSock);
    46         if (PR_FAILURE == status) {
    47             fprintf(stderr, "PR_Close failed\n");
    48             exit(1);
    49         }
    50     }
    51 }
    53 int main(int argc, char **argv)
    54 {
    55     PRNetAddr serverAddr;
    56     PRFileDesc *dummySock;
    57     PRFileDesc *listenSock;
    58     PRFileDesc *clientSock;
    59     PRThread *dummyThread;
    60     PRThread **serverThreads;
    61     PRStatus status;
    62     PRUint16 port;
    63     int idx;
    64     PRInt32 nbytes;
    65     char buf[1024];
    67     serverThreads = (PRThread **)
    68             PR_Malloc(num_server_threads * sizeof(PRThread *));
    69     if (NULL == serverThreads) {
    70         fprintf(stderr, "PR_Malloc failed\n");
    71         exit(1);
    72     }
    74     /*
    75      * Create a dummy listening socket and have the first
    76      * (dummy) thread listen on it.  This is to ensure that
    77      * the first thread becomes the I/O continuation thread
    78      * in the pthreads implementation (see ptio.c) and remains
    79      * so throughout the test, so that we never have to
    80      * recycle the I/O continuation thread.
    81      */
    82     dummySock = PR_NewTCPSocket();
    83     if (NULL == dummySock) {
    84         fprintf(stderr, "PR_NewTCPSocket failed\n");
    85         exit(1);
    86     }
    87     memset(&serverAddr, 0, sizeof(serverAddr));
    88     status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
    89     if (PR_FAILURE == status) {
    90         fprintf(stderr, "PR_InitializeNetAddr failed\n");
    91         exit(1);
    92     }
    93     status = PR_Bind(dummySock, &serverAddr);
    94     if (PR_FAILURE == status) {
    95         fprintf(stderr, "PR_Bind failed\n");
    96         exit(1);
    97     }
    98     status = PR_Listen(dummySock, 5);
    99     if (PR_FAILURE == status) {
   100         fprintf(stderr, "PR_Listen failed\n");
   101         exit(1);
   102     }
   104     listenSock = PR_NewTCPSocket();
   105     if (NULL == listenSock) {
   106         fprintf(stderr, "PR_NewTCPSocket failed\n");
   107         exit(1);
   108     }
   109     memset(&serverAddr, 0, sizeof(serverAddr));
   110     status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
   111     if (PR_FAILURE == status) {
   112         fprintf(stderr, "PR_InitializeNetAddr failed\n");
   113         exit(1);
   114     }
   115     status = PR_Bind(listenSock, &serverAddr);
   116     if (PR_FAILURE == status) {
   117         fprintf(stderr, "PR_Bind failed\n");
   118         exit(1);
   119     }
   120     status = PR_GetSockName(listenSock, &serverAddr);
   121     if (PR_FAILURE == status) {
   122         fprintf(stderr, "PR_GetSockName failed\n");
   123         exit(1);
   124     }
   125     port = PR_ntohs(serverAddr.inet.port);
   126     status = PR_Listen(listenSock, 5);
   127     if (PR_FAILURE == status) {
   128         fprintf(stderr, "PR_Listen failed\n");
   129         exit(1);
   130     }
   132     printf("creating dummy thread\n");
   133     fflush(stdout);
   134     dummyThread = PR_CreateThread(PR_USER_THREAD,
   135             ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL,
   136             thread_scope, PR_JOINABLE_THREAD, 0);
   137     if (NULL == dummyThread) {
   138         fprintf(stderr, "PR_CreateThread failed\n");
   139         exit(1);
   140     }
   141     printf("sleeping one second before creating server threads\n");
   142     fflush(stdout);
   143     PR_Sleep(PR_SecondsToInterval(1));
   144     for (idx = 0; idx < num_server_threads; idx++) {
   145         serverThreads[idx] = PR_CreateThread(PR_USER_THREAD,
   146                 ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL,
   147                 thread_scope, PR_JOINABLE_THREAD, 0);
   148         if (NULL == serverThreads[idx]) {
   149             fprintf(stderr, "PR_CreateThread failed\n");
   150             exit(1);
   151         }
   152     }
   154     memset(&serverAddr, 0, sizeof(serverAddr));
   155     PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr);
   156     clientSock = PR_NewTCPSocket();
   157     if (NULL == clientSock) {
   158         fprintf(stderr, "PR_NewTCPSocket failed\n");
   159         exit(1);
   160     }
   161     printf("sleeping one second before connecting\n");
   162     fflush(stdout);
   163     PR_Sleep(PR_SecondsToInterval(1));
   164     status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT);
   165     if (PR_FAILURE == status) {
   166         fprintf(stderr, "PR_Connect failed\n");
   167         exit(1);
   168     }
   169     nbytes = PR_Read(clientSock, buf, sizeof(buf));
   170     if (nbytes != 0) {
   171         fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes);
   172         exit(1);
   173     }
   174     status = PR_Close(clientSock);
   175     if (PR_FAILURE == status) {
   176         fprintf(stderr, "PR_Close failed\n");
   177         exit(1);
   178     }
   179     printf("sleeping one second before shutting down server threads\n");
   180     fflush(stdout);
   181     PR_Sleep(PR_SecondsToInterval(1));
   183     exit_flag = PR_TRUE;
   184     status = PR_Interrupt(dummyThread);
   185     if (PR_FAILURE == status) {
   186         fprintf(stderr, "PR_Interrupt failed\n");
   187         exit(1);
   188     }
   189     status = PR_JoinThread(dummyThread);
   190     if (PR_FAILURE == status) {
   191         fprintf(stderr, "PR_JoinThread failed\n");
   192         exit(1);
   193     }
   194     for (idx = 0; idx < num_server_threads; idx++) {
   195         status = PR_Interrupt(serverThreads[idx]);
   196         if (PR_FAILURE == status) {
   197             fprintf(stderr, "PR_Interrupt failed\n");
   198             exit(1);
   199         }
   200         status = PR_JoinThread(serverThreads[idx]);
   201         if (PR_FAILURE == status) {
   202             fprintf(stderr, "PR_JoinThread failed\n");
   203             exit(1);
   204         }
   205     }
   206     PR_Free(serverThreads);
   207     status = PR_Close(dummySock);
   208     if (PR_FAILURE == status) {
   209         fprintf(stderr, "PR_Close failed\n");
   210         exit(1);
   211     }
   212     status = PR_Close(listenSock);
   213     if (PR_FAILURE == status) {
   214         fprintf(stderr, "PR_Close failed\n");
   215         exit(1);
   216     }
   218     printf("PASS\n");
   219     return 0;
   220 }

mercurial