~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to system/lib/libcxxabi/src/cxa_exception_storage.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===--------------------- cxa_exception_storage.cpp ----------------------===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is dual licensed under the MIT and the University of Illinois Open
 
6
// Source Licenses. See LICENSE.TXT for details.
 
7
//
 
8
//  
 
9
//  This file implements the storage for the "Caught Exception Stack"
 
10
//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html (section 2.2.2)
 
11
//  
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
#include "cxa_exception.hpp"
 
15
 
 
16
#ifdef HAS_THREAD_LOCAL
 
17
 
 
18
namespace __cxxabiv1 {
 
19
 
 
20
namespace {
 
21
    __cxa_eh_globals * __globals () {
 
22
        static thread_local __cxa_eh_globals eh_globals;
 
23
        return &eh_globals;
 
24
        }
 
25
    }
 
26
 
 
27
extern "C" {
 
28
    __cxa_eh_globals * __cxa_get_globals      () { return __globals (); }
 
29
    __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); }
 
30
    }
 
31
}
 
32
 
 
33
#else
 
34
 
 
35
#include <pthread.h>
 
36
#include <cstdlib>          // for calloc, free
 
37
#include "abort_message.h"
 
38
 
 
39
//  In general, we treat all pthread errors as fatal.
 
40
//  We cannot call std::terminate() because that will in turn
 
41
//  call __cxa_get_globals() and cause infinite recursion.
 
42
 
 
43
namespace __cxxabiv1 {
 
44
namespace {
 
45
    pthread_key_t  key_;
 
46
    pthread_once_t flag_ = PTHREAD_ONCE_INIT;
 
47
 
 
48
    void destruct_ (void *p) {
 
49
        std::free ( p );
 
50
        if ( 0 != ::pthread_setspecific ( key_, NULL ) ) 
 
51
            abort_message("cannot zero out thread value for __cxa_get_globals()");
 
52
        }
 
53
 
 
54
    void construct_ () {
 
55
        if ( 0 != pthread_key_create ( &key_, destruct_ ) )
 
56
            abort_message("cannot create pthread key for __cxa_get_globals()");
 
57
        }
 
58
}   
 
59
 
 
60
extern "C" {
 
61
    __cxa_eh_globals * __cxa_get_globals () {
 
62
    //  Try to get the globals for this thread
 
63
        __cxa_eh_globals* retVal = __cxa_get_globals_fast ();
 
64
    
 
65
    //  If this is the first time we've been asked for these globals, create them
 
66
        if ( NULL == retVal ) {
 
67
            retVal = static_cast<__cxa_eh_globals*>
 
68
                        (std::calloc (1, sizeof (__cxa_eh_globals)));
 
69
            if ( NULL == retVal )
 
70
                abort_message("cannot allocate __cxa_eh_globals");
 
71
            if ( 0 != pthread_setspecific ( key_, retVal ) )
 
72
               abort_message("pthread_setspecific failure in __cxa_get_globals()");
 
73
           }
 
74
        return retVal;
 
75
        }
 
76
 
 
77
    // Note that this implementation will reliably return NULL if not
 
78
    // preceded by a call to __cxa_get_globals().  This is an extension
 
79
    // to the Itanium ABI and is taken advantage of in several places in
 
80
    // libc++abi.
 
81
    __cxa_eh_globals * __cxa_get_globals_fast () {
 
82
    //  First time through, create the key.
 
83
        if (0 != pthread_once(&flag_, construct_))
 
84
            abort_message("pthread_once failure in __cxa_get_globals_fast()");
 
85
//        static int init = construct_();
 
86
        return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_));
 
87
        }
 
88
    
 
89
}
 
90
}
 
91
#endif