/* -*- 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/. */

/***********************************************************************
**
** Name: dbmalloc1.c
**
** Description: Join tests user - user
**
** Modification History:
**
** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
**           AGarcia- Converted the test to accomodate the debug_mode flag.
**           The debug mode will print all of the printfs associated with this test.
**           The regress mode will be the default mode. Since the regress tool limits
**           the output to a one line status:PASS or FAIL,all of the printf statements
**           have been handled with an if (debug_mode) statement.
** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
**          recognize the return code from tha main program.
***********************************************************************/

/***********************************************************************
** Includes
***********************************************************************/
/* Used to get the command line option */
#include "plgetopt.h"

#include "nspr.h"

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

PRIntn failed_already=0;
PRIntn debug_mode;


/*
    Program to test joining of threads.  Two threads are created.  One
    to be waited upon until it has started.  The other to join after it has
    completed.
*/


static void lowPriority(void *arg)
{
}

static void highPriority(void *arg)
{
}

void runTest(PRThreadScope scope1, PRThreadScope scope2)
{
    PRThread *low,*high;

    /* create the low and high priority threads */

    low = PR_CreateThread(PR_USER_THREAD,
                          lowPriority, 0,
                          PR_PRIORITY_LOW,
                          scope1,
                          PR_JOINABLE_THREAD,
                          0);
    if (!low) {
        if (debug_mode) {
            printf("\tcannot create low priority thread\n");
        }
        else {
            failed_already=1;
        }
        return;
    }

    high = PR_CreateThread(PR_USER_THREAD,
                           highPriority, 0,
                           PR_PRIORITY_HIGH,
                           scope2,
                           PR_JOINABLE_THREAD,
                           0);
    if (!high) {
        if (debug_mode) {
            printf("\tcannot create high priority thread\n");
        }
        else {
            failed_already=1;
        }
        return;
    }

    /* Do the joining for both threads */
    if (PR_JoinThread(low) == PR_FAILURE) {
        if (debug_mode) {
            printf("\tcannot join low priority thread\n");
        }
        else {
            failed_already=1;
        }
        return;
    } else {
        if (debug_mode) {
            printf("\tjoined low priority thread\n");
        }
    }
    if (PR_JoinThread(high) == PR_FAILURE) {
        if (debug_mode) {
            printf("\tcannot join high priority thread\n");
        }
        else {
            failed_already=1;
        }
        return;
    } else {
        if (debug_mode) {
            printf("\tjoined high priority thread\n");
        }
    }
}

static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
{
    /* The command line argument: -d is used to determine if the test is being run
    in debug mode. The regress tool requires only one line output:PASS or FAIL.
    All of the printfs associated with this test has been handled with a if (debug_mode)
    test.
    Usage: test_name -d
    */

    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_mode = 1;
                break;
            default:
                break;
        }
    }
    PL_DestroyOptState(opt);

    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    /* main test */
    if (debug_mode) {
        printf("User-User test\n");
    }
    runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD);

    if(failed_already)
    {
        printf("FAIL\n");
        return 1;
    } else
    {
        printf("PASS\n");
        return 0;
    }


}


int main(int argc, char **argv)
{
    PRIntn rv;

    PR_STDIO_INIT();
    rv = PR_Initialize(RealMain, argc, argv, 0);
    return rv;
}  /* main */
