~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/erl_interface/src/misc/ei_pthreads.c

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include "ei.h"
25
25
#include "ei_locking.h"
26
26
 
 
27
#ifdef __WIN32__
 
28
#ifdef USE_DECLSPEC_THREAD
27
29
/* Define (and initialize) the variable __erl_errno */
28
30
volatile __declspec(thread) int __erl_errno = 0;
 
31
#else
 
32
static volatile DWORD errno_tls_index = TLS_OUT_OF_INDEXES;
 
33
static LONG volatile tls_init_mutex = 0;
 
34
#endif
 
35
#endif
29
36
 
30
37
#if defined(VXWORKS)
31
38
 
33
40
   Moved to each of the erl_*threads.c files, as they seem to know how
34
41
   to get thread-safety. 
35
42
*/
36
 
 
 
43
static volatile int __erl_errno;
37
44
volatile int *__erl_errno_place(void)
38
45
{
39
46
    /* This check is somewhat insufficient, double task var entries will occur
48
55
 
49
56
#if defined(__WIN32__)
50
57
 
 
58
#ifdef USE_DECLSPEC_THREAD
 
59
 
51
60
volatile int *__erl_errno_place(void)
52
61
{
53
62
    return &__erl_errno;
54
63
}
55
64
 
 
65
#else
 
66
static void tls_init_once(void)
 
67
{
 
68
 
 
69
    if (errno_tls_index != TLS_OUT_OF_INDEXES) {
 
70
        return;
 
71
    }
 
72
    if (InterlockedExchange((LPLONG) &tls_init_mutex,1L) == 0) {
 
73
        /* I was first */
 
74
        errno_tls_index = TlsAlloc();
 
75
        if (errno_tls_index == TLS_OUT_OF_INDEXES) {
 
76
            fprintf(stderr, 
 
77
                    "FATAL ERROR: can not allocate TLS index for "
 
78
                    "erl_errno (error code = %d)!\n",GetLastError());
 
79
            exit(1);
 
80
        }
 
81
    } else {
 
82
        while (errno_tls_index == TLS_OUT_OF_INDEXES) {
 
83
            SwitchToThread();
 
84
        }
 
85
    }
 
86
}
 
87
 
 
88
volatile int *__erl_errno_place(void)
 
89
{
 
90
    volatile int *ptr;
 
91
    tls_init_once();
 
92
    ptr = TlsGetValue(errno_tls_index);
 
93
    if (ptr == NULL) {
 
94
        ptr = malloc(sizeof(int));
 
95
        *ptr = 0;
 
96
        TlsSetValue(errno_tls_index, (PVOID) ptr);
 
97
    }
 
98
    return ptr;
 
99
}
 
100
 
 
101
#endif /* USE_DECLSPEC_THREAD */
 
102
 
56
103
#endif /* __WIN32__ */
57
104
 
58
105
#if defined(_REENTRANT) && !defined(VXWORKS) && !defined(__WIN32__)
123
170
 
124
171
/*
125
172
 * Return a pointer to the erl_errno locus.
126
 
 * If pthread functions fail we fall back to using __erl_errno
 
173
 * If pthread functions fail we fall back to using fallback_errno
127
174
 * so that the main thread (actually not a thread in all ascpects)
128
175
 * still will set and get an erl_errno value.
129
 
 * FIXME is this a bit too nice???
130
 
 * If -lpthread is not given on Solaris __erl_errno will be used
131
 
 * but it costs some....,
 
176
 * Actually this is a bit to nice, it would be preferrable to exit fatal
 
177
 * as we do on windows, but we might break some code with one thread
 
178
 * but still compiled with -D_REENTRANT, so we'll leave it here.
132
179
 */
133
180
volatile int *__erl_errno_place(void)
134
181
{
135
182
    int *erl_errno_p;
 
183
    static volatile int use_fallback = 0;
 
184
    static volatile int fallback_errno = 0;
 
185
 
 
186
    if (use_fallback) {
 
187
        return &fallback_errno;
 
188
    }   
136
189
 
137
190
    /* This will create the key once for all threads */
138
 
    if (pthread_once(&erl_errno_key_once, erl_errno_key_alloc) != 0)
139
 
        return &__erl_errno;
 
191
    if (pthread_once(&erl_errno_key_once, erl_errno_key_alloc) != 0) {
 
192
        use_fallback = 1;
 
193
        return &fallback_errno;
 
194
    }
140
195
 
141
196
    /* This is the normal case, return the pointer to the data */
142
 
    if ((erl_errno_p = pthread_getspecific(erl_errno_key)) != NULL)
 
197
    if ((erl_errno_p = pthread_getspecific(erl_errno_key)) != NULL) {
143
198
        return erl_errno_p;
 
199
    }
144
200
 
145
 
    /* Case where it is the first time we access this data in this thread. */
146
 
    /* FIXME check malloc but what to do????? */
147
 
    erl_errno_p = malloc(sizeof(int));
 
201
    if ((erl_errno_p = malloc(sizeof(int))) == NULL) {
 
202
        use_fallback = 1;
 
203
        return &fallback_errno;
 
204
    }
148
205
 
149
206
    if (pthread_setspecific(erl_errno_key, erl_errno_p) != 0 ||
150
207
        (erl_errno_p = pthread_getspecific(erl_errno_key)) == NULL) {
151
208
        free(erl_errno_p);
152
 
        return &__erl_errno;
 
209
        return &fallback_errno;
153
210
    }
154
211
 
155
212
    return erl_errno_p;