Home | History | Annotate | Line # | Download | only in libpthread
      1 /*
      2  * Copyright (c) 2016 Tavian Barnes. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     14  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     15  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     23  * POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include <sys/cdefs.h>
     27 __RCSID("$NetBSD: h_thread_local_dtor.cpp,v 1.1 2017/07/11 15:21:36 joerg Exp $");
     28 
     29 #include <cstdlib>
     30 #include <thread>
     31 
     32 static int seq;
     33 
     34 class OrderChecker {
     35 public:
     36   explicit OrderChecker(int n) : n_{n} { }
     37 
     38   ~OrderChecker() {
     39     if (seq != n_) {
     40       printf("Unexpected sequence point: %d\n", 3);
     41       _Exit(1);
     42     }
     43     ++seq;
     44   }
     45 
     46 private:
     47   int n_;
     48 };
     49 
     50 template <int ID>
     51 class CreatesThreadLocalInDestructor {
     52 public:
     53   ~CreatesThreadLocalInDestructor() {
     54     thread_local OrderChecker checker{ID};
     55   }
     56 };
     57 
     58 OrderChecker global{7};
     59 
     60 void thread_fn() {
     61   static OrderChecker fn_static{5};
     62   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
     63   thread_local OrderChecker fn_thread_local{1};
     64   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
     65 }
     66 
     67 int main() {
     68   static OrderChecker fn_static{6};
     69 
     70   std::thread{thread_fn}.join();
     71   if (seq != 3) {
     72     printf("Unexpected sequence point: %d\n", 3);
     73     _Exit(1);
     74   }
     75 
     76   thread_local OrderChecker fn_thread_local{4};
     77   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
     78 
     79   return 0;
     80 }
     81