/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * File: multiacc.c
 *
 * Description:
 * This test creates multiple threads that accept on the
 * same listening socket.
 */

#include "nspr.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_SERVER_THREADS 10

static int num_server_threads = NUM_SERVER_THREADS;
static PRThreadScope thread_scope = PR_GLOBAL_THREAD;
static PRBool exit_flag = PR_FALSE;

static void ServerThreadFunc(void *arg)
{
    PRFileDesc *listenSock = (PRFileDesc *) arg;
    PRFileDesc *acceptSock;
    PRErrorCode err;
    PRStatus status;

    while (!exit_flag) {
        acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
        if (NULL == acceptSock) {
            err = PR_GetError();
            if (PR_PENDING_INTERRUPT_ERROR == err) {
                printf("server thread is interrupted\n");
                fflush(stdout);
                continue;
            }
            fprintf(stderr, "PR_Accept failed: %d\n", err);
            exit(1);
        }
        status = PR_Close(acceptSock);
        if (PR_FAILURE == status) {
            fprintf(stderr, "PR_Close failed\n");
            exit(1);
        }
    }
}

int main(int argc, char **argv)
{
    PRNetAddr serverAddr;
    PRFileDesc *dummySock;
    PRFileDesc *listenSock;
    PRFileDesc *clientSock;
    PRThread *dummyThread;
    PRThread **serverThreads;
    PRStatus status;
    PRUint16 port;
    int idx;
    PRInt32 nbytes;
    char buf[1024];

    serverThreads = (PRThread **)
            PR_Malloc(num_server_threads * sizeof(PRThread *));
    if (NULL == serverThreads) {
        fprintf(stderr, "PR_Malloc failed\n");
        exit(1);
    }

    /*
     * Create a dummy listening socket and have the first
     * (dummy) thread listen on it.  This is to ensure that
     * the first thread becomes the I/O continuation thread
     * in the pthreads implementation (see ptio.c) and remains
     * so throughout the test, so that we never have to
     * recycle the I/O continuation thread.
     */
    dummySock = PR_NewTCPSocket();
    if (NULL == dummySock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    memset(&serverAddr, 0, sizeof(serverAddr));
    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    status = PR_Bind(dummySock, &serverAddr);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    status = PR_Listen(dummySock, 5);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }

    listenSock = PR_NewTCPSocket();
    if (NULL == listenSock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    memset(&serverAddr, 0, sizeof(serverAddr));
    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    status = PR_Bind(listenSock, &serverAddr);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    status = PR_GetSockName(listenSock, &serverAddr);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_GetSockName failed\n");
        exit(1);
    }
    port = PR_ntohs(serverAddr.inet.port);
    status = PR_Listen(listenSock, 5);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }

    printf("creating dummy thread\n");
    fflush(stdout);
    dummyThread = PR_CreateThread(PR_USER_THREAD,
            ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL,
            thread_scope, PR_JOINABLE_THREAD, 0);
    if (NULL == dummyThread) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    printf("sleeping one second before creating server threads\n");
    fflush(stdout);
    PR_Sleep(PR_SecondsToInterval(1));
    for (idx = 0; idx < num_server_threads; idx++) {
        serverThreads[idx] = PR_CreateThread(PR_USER_THREAD,
                ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL,
                thread_scope, PR_JOINABLE_THREAD, 0);
        if (NULL == serverThreads[idx]) {
            fprintf(stderr, "PR_CreateThread failed\n");
            exit(1);
        }
    }

    memset(&serverAddr, 0, sizeof(serverAddr));
    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr);
    clientSock = PR_NewTCPSocket();
    if (NULL == clientSock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    printf("sleeping one second before connecting\n");
    fflush(stdout);
    PR_Sleep(PR_SecondsToInterval(1));
    status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Connect failed\n");
        exit(1);
    }
    nbytes = PR_Read(clientSock, buf, sizeof(buf));
    if (nbytes != 0) {
        fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes);
        exit(1);
    }
    status = PR_Close(clientSock);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    printf("sleeping one second before shutting down server threads\n");
    fflush(stdout);
    PR_Sleep(PR_SecondsToInterval(1));

    exit_flag = PR_TRUE;
    status = PR_Interrupt(dummyThread);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Interrupt failed\n");
        exit(1);
    }
    status = PR_JoinThread(dummyThread);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    for (idx = 0; idx < num_server_threads; idx++) {
        status = PR_Interrupt(serverThreads[idx]);
        if (PR_FAILURE == status) {
            fprintf(stderr, "PR_Interrupt failed\n");
            exit(1);
        }
        status = PR_JoinThread(serverThreads[idx]);
        if (PR_FAILURE == status) {
            fprintf(stderr, "PR_JoinThread failed\n");
            exit(1);
        }
    }
    PR_Free(serverThreads);
    status = PR_Close(dummySock);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    status = PR_Close(listenSock);
    if (PR_FAILURE == status) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }

    printf("PASS\n");
    return 0;
}
