1bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes/* 2bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 3bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 4bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * you may not use this file except in compliance with the License. 6bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * You may obtain a copy of the License at 7bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 8bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 10bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * See the License for the specific language governing permissions and 14bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * limitations under the License. 15bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes */ 16bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 17bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <gtest/gtest.h> 18bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 19bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <errno.h> 20bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <pthread.h> 214d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes#include <unistd.h> 22bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 23bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott HughesTEST(pthread, pthread_key_create) { 24bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes pthread_key_t key; 25bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 26bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 27bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes // Can't delete a key that's already been deleted. 28bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(EINVAL, pthread_key_delete(key)); 29bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes} 304d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 314d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* IdFn(void* arg) { 324d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return arg; 334d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 344d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 354d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* SleepFn(void* arg) { 364d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes sleep(reinterpret_cast<unsigned int>(arg)); 374d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return NULL; 384d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 394d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 404d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* JoinFn(void* arg) { 414d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 424d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 434d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 444d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_create) { 454d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* expected_result = reinterpret_cast<void*>(123); 464d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // Can we create a thread? 474d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t; 484d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 494d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If we join, do we get the expected value back? 504d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 514d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 524d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(expected_result, result); 534d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 544d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 554d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_join_after_detach) { 564d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 574d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 584d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 594d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // After a pthread_detach... 604d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 614d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 624d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...pthread_join should fail. 634d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 644d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(EINVAL, pthread_join(t1, &result)); 654d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 664d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 674d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_op_detach_after_join) { 684d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 694d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(1))); 704d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 714d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If thread 2 is already waiting to join thread 1... 724d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t2; 734d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 744d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 754d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...a call to pthread_detach on thread 1 will "succeed"... 764d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 774d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 784d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...but the join still goes ahead. 794d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* join_result; 804d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t2, &join_result)); 814d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(EINVAL, reinterpret_cast<int>(join_result)); 824d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 83