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