michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /*********************************************************************** michael@0: ** 1996 - Netscape Communications Corporation michael@0: ** michael@0: ** Name: attach.c michael@0: ** michael@0: ** Description: Platform-specific code to create a native thread. The native thread will michael@0: ** repeatedly call PR_AttachThread and PR_DetachThread. The michael@0: ** primordial thread waits for this new thread to finish. michael@0: ** michael@0: ** Modification History: michael@0: ** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. michael@0: ** The debug mode will print all of the printfs associated with this test. michael@0: ** The regress mode will be the default mode. Since the regress tool limits michael@0: ** the output to a one line status:PASS or FAIL,all of the printf statements michael@0: ** have been handled with an if (debug_mode) statement. michael@0: ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to michael@0: ** recognize the return code from tha main program. michael@0: ** 12-June-97 Revert to return code 0 and 1. michael@0: ***********************************************************************/ michael@0: michael@0: /*********************************************************************** michael@0: ** Includes michael@0: ***********************************************************************/ michael@0: michael@0: /* Used to get the command line option */ michael@0: #include "nspr.h" michael@0: #include "pprthred.h" michael@0: #include "plgetopt.h" michael@0: michael@0: #include michael@0: michael@0: #ifdef WIN32 michael@0: #include michael@0: #include michael@0: #elif defined(_PR_PTHREADS) michael@0: #include michael@0: #include "md/_pth.h" michael@0: #elif defined(IRIX) michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #elif defined(SOLARIS) michael@0: #include michael@0: #elif defined(OS2) michael@0: #define INCL_DOS michael@0: #define INCL_ERRORS michael@0: #include michael@0: #include michael@0: #elif defined(XP_BEOS) michael@0: #include michael@0: #endif michael@0: michael@0: #define DEFAULT_COUNT 1000 michael@0: PRIntn failed_already=0; michael@0: PRIntn debug_mode; michael@0: michael@0: michael@0: int count; michael@0: michael@0: michael@0: static void michael@0: AttachDetach(void) michael@0: { michael@0: PRThread *me; michael@0: PRInt32 index; michael@0: michael@0: for (index=0;indexoption) michael@0: { michael@0: case 'd': /* debug mode */ michael@0: debug_mode = 1; michael@0: break; michael@0: case 'c': /* loop count */ michael@0: count = atoi(opt->value); michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: PL_DestroyOptState(opt); michael@0: michael@0: #if defined(WIN16) michael@0: printf("attach: This test is not valid for Win16\n"); michael@0: goto exit_now; michael@0: #endif michael@0: michael@0: if(0 == count) count = DEFAULT_COUNT; michael@0: michael@0: /* michael@0: * To force the implicit initialization of nspr20 michael@0: */ michael@0: PR_SetError(0, 0); michael@0: PR_STDIO_INIT(); michael@0: michael@0: /* michael@0: * Platform-specific code to create a native thread. The native michael@0: * thread will repeatedly call PR_AttachThread and PR_DetachThread. michael@0: * The primordial thread waits for this new thread to finish. michael@0: */ michael@0: michael@0: #ifdef _PR_PTHREADS michael@0: michael@0: rv = _PT_PTHREAD_ATTR_INIT(&attr); michael@0: if (debug_mode) PR_ASSERT(0 == rv); michael@0: else if (0 != rv) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #ifndef _PR_DCETHREADS michael@0: rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); michael@0: if (debug_mode) PR_ASSERT(0 == rv); michael@0: else if (0 != rv) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: #endif /* !_PR_DCETHREADS */ michael@0: rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL); michael@0: if (rv != 0) { michael@0: fprintf(stderr, "thread creation failed: error code %d\n", rv); michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: else { michael@0: if (debug_mode) michael@0: printf ("thread creation succeeded \n"); michael@0: michael@0: } michael@0: rv = _PT_PTHREAD_ATTR_DESTROY(&attr); michael@0: if (debug_mode) PR_ASSERT(0 == rv); michael@0: else if (0 != rv) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: rv = pthread_join(threadID, NULL); michael@0: if (debug_mode) PR_ASSERT(0 == rv); michael@0: else if (0 != rv) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #elif defined(SOLARIS) michael@0: michael@0: rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID); michael@0: if (rv != 0) { michael@0: if(!debug_mode) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } else michael@0: fprintf(stderr, "thread creation failed: error code %d\n", rv); michael@0: } michael@0: rv = thr_join(threadID, NULL, NULL); michael@0: if (debug_mode) PR_ASSERT(0 == rv); michael@0: else if (0 != rv) michael@0: { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: michael@0: #elif defined(WIN32) michael@0: michael@0: hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL, michael@0: STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID); michael@0: if (hThread == 0) { michael@0: fprintf(stderr, "thread creation failed: error code %d\n", michael@0: GetLastError()); michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: rv = WaitForSingleObject(hThread, INFINITE); michael@0: if (debug_mode)PR_ASSERT(rv != WAIT_FAILED); michael@0: else if (rv == WAIT_FAILED) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #elif defined(IRIX) michael@0: michael@0: threadID = sproc(threadStartFunc, PR_SALL, NULL); michael@0: if (threadID == -1) { michael@0: michael@0: fprintf(stderr, "thread creation failed: error code %d\n", michael@0: errno); michael@0: failed_already=1; michael@0: goto exit_now; michael@0: michael@0: } michael@0: else { michael@0: if (debug_mode) michael@0: printf ("thread creation succeeded \n"); michael@0: sleep(3); michael@0: goto exit_now; michael@0: } michael@0: rv = waitpid(threadID, NULL, 0); michael@0: if (debug_mode) PR_ASSERT(rv != -1); michael@0: else if (rv != -1) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #elif defined(OS2) michael@0: michael@0: threadID = (TID) _beginthread((void *)threadStartFunc, NULL, michael@0: 32768, NULL); michael@0: if (threadID == -1) { michael@0: fprintf(stderr, "thread creation failed: error code %d\n", errno); michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: rv = DosWaitThread(&threadID, DCWW_WAIT); michael@0: if (debug_mode) { michael@0: PR_ASSERT(rv == NO_ERROR); michael@0: } else if (rv != NO_ERROR) { michael@0: failed_already=1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #elif defined(XP_BEOS) michael@0: michael@0: threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL); michael@0: if (threadID <= B_ERROR) { michael@0: fprintf(stderr, "thread creation failed: error code %08lx\n", threadID); michael@0: failed_already = 1; michael@0: goto exit_now; michael@0: } michael@0: if (resume_thread(threadID) != B_OK) { michael@0: fprintf(stderr, "failed starting thread: error code %08lx\n", threadID); michael@0: failed_already = 1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: waitRV = wait_for_thread(threadID, &threadRV); michael@0: if (debug_mode) michael@0: PR_ASSERT(waitRV == B_OK); michael@0: else if (waitRV != B_OK) { michael@0: failed_already = 1; michael@0: goto exit_now; michael@0: } michael@0: michael@0: #else michael@0: if (!debug_mode) michael@0: failed_already=1; michael@0: else michael@0: printf("The attach test does not apply to this platform because\n" michael@0: "either this platform does not have native threads or the\n" michael@0: "test needs to be written for this platform.\n"); michael@0: goto exit_now; michael@0: #endif michael@0: michael@0: exit_now: michael@0: if(failed_already) michael@0: return 1; michael@0: else michael@0: return 0; michael@0: }