1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <stdio.h>
17 #include <stdlib.h>
18 
19 #include <string>
20 
21 // use external control number from main test
22 static std::string* atexit_sequence = NULL;
23 static bool* atexit_valid_this_in_static_dtor = NULL;
24 
25 static class AtExitStaticClass {
26  public:
AtExitStaticClass()27   AtExitStaticClass() { expected_this = this; }
~AtExitStaticClass()28   ~AtExitStaticClass() {
29     if (atexit_valid_this_in_static_dtor) {
30       *atexit_valid_this_in_static_dtor = (expected_this == this);
31     }
32   }
33  private:
34   static const AtExitStaticClass* expected_this;
35 
36 } static_obj;
37 
38 const AtExitStaticClass* AtExitStaticClass::expected_this = NULL;
39 
40 // 4
atexit_handler_from_atexit_from_atexit2()41 static void atexit_handler_from_atexit_from_atexit2() {
42   *atexit_sequence += " on";
43 }
44 
45 // 3
atexit_handler_from_atexit_from_atexit1()46 static void atexit_handler_from_atexit_from_atexit1() {
47   *atexit_sequence += " sat";
48 }
49 
50 // 2
atexit_handler_from_atexit()51 static void atexit_handler_from_atexit() {
52   *atexit_sequence += " Dumpty";
53   // register 2 others
54   atexit(atexit_handler_from_atexit_from_atexit2);
55   atexit(atexit_handler_from_atexit_from_atexit1);
56 }
57 
58 // 1
atexit_handler_with_atexit()59 static void atexit_handler_with_atexit() {
60   *atexit_sequence += "Humpty";
61   atexit(atexit_handler_from_atexit);
62 }
63 
64 // last
atexit_handler_regular()65 static void atexit_handler_regular() {
66   *atexit_sequence += " a wall";
67 }
68 
register_atexit(std::string * sequence,bool * valid_this_in_static_dtor)69 extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor) {
70   atexit_sequence = sequence;
71   atexit_valid_this_in_static_dtor = valid_this_in_static_dtor;
72   atexit(atexit_handler_regular);
73   atexit(atexit_handler_with_atexit);
74 }
75 
76