TEST(pthread, pthread_no_op_detach_after_join) { SpinFunctionHelper spinhelper; pthread_t t1; ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); // If thread 2 is already waiting to join thread 1... pthread_t t2; ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); sleep(1); // (Give t2 a chance to call pthread_join.) #if defined(__BIONIC__) ASSERT_EQ(EINVAL, pthread_detach(t1)); #else ASSERT_EQ(0, pthread_detach(t1)); #endif AssertDetached(t1, false); spinhelper.UnSpin(); // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). void* join_result; ASSERT_EQ(0, pthread_join(t2, &join_result)); ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); }
TEST(pthread, pthread_no_join_after_detach) { pthread_t t1; ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); // After a pthread_detach... ASSERT_EQ(0, pthread_detach(t1)); AssertDetached(t1, true); // ...pthread_join should fail. ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); }
TEST(pthread, pthread_no_join_after_detach) { SpinFunctionHelper spinhelper; pthread_t t1; ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); // After a pthread_detach... ASSERT_EQ(0, pthread_detach(t1)); AssertDetached(t1, true); // ...pthread_join should fail. ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); }
TEST(pthread, pthread_no_op_detach_after_join) { bool done = false; pthread_t t1; ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); // If thread 2 is already waiting to join thread 1... pthread_t t2; ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); sleep(1); // (Give t2 a chance to call pthread_join.) // ...a call to pthread_detach on thread 1 will "succeed" (silently fail)... ASSERT_EQ(0, pthread_detach(t1)); AssertDetached(t1, false); done = true; // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). void* join_result; ASSERT_EQ(0, pthread_join(t2, &join_result)); ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); }