TEST(JoinTest, joinExitedThread) { omrthread_t helperThr = NULL; ASSERT_NO_FATAL_FAILURE(createThread(&helperThr, FALSE, J9THREAD_CREATE_JOINABLE, doNothingHelper, NULL)); /* hopefully wait long enough for the child thread to exit */ ASSERT_EQ(J9THREAD_SUCCESS, omrthread_sleep(3000)); VERBOSE_JOIN(helperThr, J9THREAD_SUCCESS); }
static uintptr_t canCreateThread(const create_attr_t *expected, const omrthread_attr_t attr) { uintptr_t status = 0; uintptr_t rc; omrthread_t handle; threaddata_t data; data.expected = expected; data.status = 0; getCurrentOsSched(&data.curPriority, &data.curPolicy); rc = J9THREAD_VERBOSE(omrthread_create_ex(&handle, (attr? &attr : J9THREAD_ATTR_DEFAULT), 1, threadmain, &data)); if (J9THREAD_SUCCESS == rc) { OSTHREAD tid = handle->handle; omrthread_resume(handle); #if defined(SPEC_PTHREAD_API) #if defined(LINUX) /* bug? Linux can return a success code, but still fail to create the thread. * NOTE: It is not guaranteed that tid 0 is invalid in all pthread implementations. */ if (0 == tid) { omrTestEnv->log(LEVEL_ERROR, " LINUX: tid 0 returned\n"); status |= CREATE_FAILED; return status; } #endif /* defined(LINUX) */ /* this may fail because omrthreads detach themselves upon exiting */ #if defined(OSX) /* OSX TODO: Why do the tests segfault in child thread when accessing &data on OSX without a 1ms sleep? */ omrthread_sleep(10); #endif /* defined(OSX) */ PTHREAD_VERBOSE(pthread_join(tid, NULL)); status |= data.status; #elif defined(SPEC_WIN_API) WaitForSingleObject(tid, INFINITE); status |= data.status; #else /* In this case, * threadmain() doesn't access the expected data, so it's ok to continue without * waiting for the child thread to complete. */ #endif /* defined(SPEC_PTHREAD_API) */ } else { status |= CREATE_FAILED; } return status; }
static int J9THREAD_PROC attachDetachHelper(void *entryArg) { omr_error_t rc = OMR_ERROR_NONE; ChildThreadData *childData = (ChildThreadData *)entryArg; OMRTestVM *testVM = childData->testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Init(&testVM->omrVM, NULL, &vmthread, "attachDetachHelper")); if (OMR_ERROR_NONE != rc) { if (OMR_ERROR_NOT_AVAILABLE == rc) { /* this is ok, it means the shutdown helper finished first */ return 0; } else { childData->childRc = rc; return -1; } } /* yield to encourage concurency */ omrthread_sleep(1); /* Fire some trace points */ const char *alphabetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; size_t stringsPerTraceBuffer = (1024 + strlen(alphabetUpper) - 1) / strlen(alphabetUpper); for (size_t i = 0; i < stringsPerTraceBuffer * 5; i += 1) { Trc_OMR_Test_String(vmthread, alphabetUpper); omrthread_yield(); } rc = OMRTEST_PRINT_ERROR(OMR_Thread_Free(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } return 0; }
TEST(JoinTest, joinLiveThread) { omrthread_t suspendedThr = NULL; omrthread_t joinHelperThr = NULL; JoinThreadHelperData helperData; /* suspend the child thread when it starts */ ASSERT_NO_FATAL_FAILURE(createThread(&suspendedThr, TRUE, J9THREAD_CREATE_JOINABLE, doNothingHelper, NULL)); /* create a thread to join on the suspended thread */ helperData.threadToJoin = suspendedThr; helperData.expectedRc = J9THREAD_SUCCESS; ASSERT_NO_FATAL_FAILURE(createThread(&joinHelperThr, FALSE, J9THREAD_CREATE_JOINABLE, joinThreadHelper, &helperData)); /* hopefully wait long enough for the join helper thread to start joining */ ASSERT_EQ(J9THREAD_SUCCESS, omrthread_sleep(3000)); /* resume the child thread */ printf("resuming suspendedThr\n"); fflush(stdout); ASSERT_EQ(1, omrthread_resume(suspendedThr)); VERBOSE_JOIN(joinHelperThr, J9THREAD_SUCCESS); }