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