Serenity Operating System
at master 86 lines 2.3 kB view raw
1/* 2 * Copyright (c) 2022, Tim Schumacher <timschumi@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8#include <pthread.h> 9 10static size_t exit_count = 0; 11 12static void exit_count_test_handler(void* data) 13{ 14 EXPECT_EQ(exit_count, reinterpret_cast<size_t>(data)); 15 exit_count++; 16} 17 18static void immediate_fail_handler(void*) 19{ 20 FAIL("Called a cleanup handler"); 21} 22 23static void* cleanup_pthread_exit_inner(void*) 24{ 25 // Push handlers in reverse order as they are taken from the top of the stack on cleanup. 26 pthread_cleanup_push(exit_count_test_handler, reinterpret_cast<void*>(2)); 27 pthread_cleanup_push(exit_count_test_handler, reinterpret_cast<void*>(1)); 28 pthread_cleanup_push(exit_count_test_handler, reinterpret_cast<void*>(0)); 29 30 pthread_exit(nullptr); 31} 32 33TEST_CASE(cleanup_pthread_exit) 34{ 35 pthread_t thread; 36 exit_count = 0; 37 38 pthread_create(&thread, nullptr, cleanup_pthread_exit_inner, nullptr); 39 40 pthread_join(thread, nullptr); 41 42 // Ensure that all exit handlers have been called. 43 EXPECT_EQ(exit_count, 3ul); 44} 45 46static void* cleanup_return_inner(void*) 47{ 48 // Returning from the main function should not call any cleanup handlers. 49 pthread_cleanup_push(immediate_fail_handler, nullptr); 50 return nullptr; 51} 52 53TEST_CASE(cleanup_return) 54{ 55 pthread_t thread; 56 pthread_create(&thread, nullptr, cleanup_return_inner, nullptr); 57 pthread_join(thread, nullptr); 58} 59 60static void* cleanup_pop_inner(void*) 61{ 62 pthread_cleanup_push(exit_count_test_handler, reinterpret_cast<void*>(1)); 63 pthread_cleanup_push(immediate_fail_handler, nullptr); 64 pthread_cleanup_push(exit_count_test_handler, reinterpret_cast<void*>(0)); 65 pthread_cleanup_push(immediate_fail_handler, nullptr); 66 67 // Popping a cleanup handler shouldn't run the callback unless `execute` is given. 68 pthread_cleanup_pop(0); 69 pthread_cleanup_pop(1); 70 pthread_cleanup_pop(0); 71 pthread_cleanup_pop(1); 72 73 return nullptr; 74} 75 76TEST_CASE(cleanup_pop) 77{ 78 pthread_t thread; 79 exit_count = 0; 80 81 pthread_create(&thread, nullptr, cleanup_pop_inner, nullptr); 82 pthread_join(thread, nullptr); 83 84 // Ensure that all exit handlers have been called. 85 EXPECT_EQ(exit_count, 2ul); 86}