Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | // BUILD(macos): $CXX main.cpp -std=c++11 -o $BUILD_DIR/thread-local-atexit-macOS.exe // BUILD(ios,tvos,watchos,bridgeos): // RUN: ./thread-local-atexit-macOS.exe #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include "test_support.h" // We create an A and a B. // While destroying B we create a C // Given that tlv_finalize has "destroy in reverse order of construction", we // must then immediately destroy C before we destroy A to maintain that invariant enum State { None, ConstructedA, ConstructedB, ConstructedC, DestroyingB, DestroyedA, DestroyedB, DestroyedC, }; struct A { A(); ~A(); }; struct B { B(); ~B(); }; struct C { C(); ~C(); }; State state; A::A() { if ( state != None ) { FAIL("should be in the 'None' state"); } state = ConstructedA; } B::B() { if ( state != ConstructedA ) { FAIL("should be in the 'ConstructedA' state"); } state = ConstructedB; } C::C() { // We construct C during B's destructor if ( state != DestroyingB ) { FAIL("should be in the 'DestroyingB' state"); } state = ConstructedC; } // We destroy B first B::~B() { if ( state != ConstructedB ) { FAIL("should be in the 'ConstructedB' state"); } state = DestroyingB; static thread_local C c; if ( state != ConstructedC ) { FAIL("should be in the 'ConstructedC' state"); } state = DestroyedB; } // Then we destroy C C::~C() { if ( state != DestroyedB ) { FAIL("should be in the 'DestroyedB' state"); } state = DestroyedC; } // And finally destroy A A::~A() { if ( state != DestroyedC ) { FAIL("should be in the 'DestroyedC' state"); } state = DestroyedA; PASS("[Success"); } static void work() { thread_local A a = {}; thread_local B b = {}; } int main(int argc, const char* argv[], const char* envp[], const char* apple[]) { work(); return 0; } |