1303795Skib/*- 2303795Skib * Copyright (c) 2016 Mahdi Mokhtari <mokhi64@gmail.com> 3303795Skib * Copyright (c) 2016 The FreeBSD Foundation 4303795Skib * All rights reserved. 5303795Skib * 6303795Skib * Redistribution and use in source and binary forms, with or without 7303795Skib * modification, are permitted provided that the following conditions 8303795Skib * are met: 9303795Skib * 1. Redistributions of source code must retain the above copyright 10303795Skib * notice, this list of conditions and the following disclaimer. 11303795Skib * 2. Redistributions in binary form must reproduce the above copyright 12303795Skib * notice, this list of conditions and the following disclaimer in the 13303795Skib * documentation and/or other materials provided with the distribution. 14303795Skib * 15303795Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16303795Skib * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17303795Skib * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18303795Skib * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19303795Skib * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20303795Skib * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21303795Skib * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22303795Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23303795Skib * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24303795Skib * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25303795Skib * SUCH DAMAGE. 26303795Skib */ 27303795Skib 28303795Skib#include <sys/cdefs.h> 29303795Skib__FBSDID("$FreeBSD$"); 30303795Skib 31303795Skib#include <dlfcn.h> 32303795Skib#include <atf-c++.hpp> 33303795Skib#include <cstdio> 34303795Skib#include <cstdlib> 35303795Skib 36303795Skibstatic FILE *output = NULL; 37303795Skib 38303795Skibstruct Foo { 39303795Skib Foo() { ATF_REQUIRE(fprintf(output, "Created\n") > 0); } 40303795Skib ~Foo() { ATF_REQUIRE(fprintf(output, "Destroyed\n") > 0); } 41303795Skib void use() { ATF_REQUIRE(fprintf(output, "Used\n") > 0); } 42303795Skib}; 43303795Skib 44303795Skibstatic thread_local Foo f; 45303795Skib 46303795Skib/* 47303795Skib * This test must not be linked to libpthread. 48303795Skib */ 49303795SkibATF_TEST_CASE_WITHOUT_HEAD(cxx__nothr); 50303795SkibATF_TEST_CASE_BODY(cxx__nothr) 51303795Skib{ 52303795Skib void *libthr_handle; 53303795Skib 54303795Skib /* Avoid coredump during f construction. */ 55303795Skib output = stderr; 56303795Skib 57303795Skib libthr_handle = dlopen("libthr.so.3", RTLD_LAZY | RTLD_GLOBAL | 58303795Skib RTLD_NOLOAD); 59303795Skib ATF_REQUIRE(libthr_handle == NULL); 60303795Skib} 61303795Skib 62303795Skibstatic void 63303795Skibcheck_local_main(void) 64303795Skib{ 65303795Skib static const char out_log[] = "Created\nUsed\nDestroyed\n"; 66303795Skib 67303795Skib fflush(output); 68303795Skib ATF_REQUIRE(atf::utils::compare_file("test_main.txt", out_log)); 69303795Skib} 70303795Skib 71303795SkibATF_TEST_CASE_WITHOUT_HEAD(cxx__thread_local_main); 72303795SkibATF_TEST_CASE_BODY(cxx__thread_local_main) 73303795Skib{ 74303795Skib 75303795Skib ATF_REQUIRE((output = fopen("test_main.txt", "w")) != NULL); 76303795Skib f.use(); 77303795Skib atexit(check_local_main); 78303795Skib} 79303795Skib 80303795Skibextern "C" int __cxa_thread_atexit(void (*)(void *), void *, void *); 81303795Skib 82303795Skibstatic void 83303795Skibagain(void *arg) 84303795Skib{ 85303795Skib 86303795Skib __cxa_thread_atexit(again, arg, &output); 87303795Skib} 88303795Skib 89303795SkibATF_TEST_CASE_WITHOUT_HEAD(cxx__thread_inf_dtors); 90303795SkibATF_TEST_CASE_BODY(cxx__thread_inf_dtors) 91303795Skib{ 92303795Skib 93303795Skib again(NULL); 94303795Skib} 95303795Skib 96303795SkibATF_INIT_TEST_CASES(tcs) 97303795Skib{ 98303795Skib 99303795Skib ATF_ADD_TEST_CASE(tcs, cxx__nothr); 100303795Skib ATF_ADD_TEST_CASE(tcs, cxx__thread_local_main); 101303795Skib ATF_ADD_TEST_CASE(tcs, cxx__thread_inf_dtors); 102303795Skib} 103