4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
42 #include <pulse/utf8.h>
43 #include <pulse/xmalloc.h>
45 #include <pulsecore/core-util.h>
46 #include <pulsecore/native-common.h>
48 #include "core-error.h"
52 static pthread_once_t cstrerror_once
= PTHREAD_ONCE_INIT
;
53 static pthread_key_t tlsstr_key
;
55 static void inittls(void) {
58 ret
= pthread_key_create(&tlsstr_key
, pa_xfree
);
60 fprintf(stderr
, __FILE__
": CRITICAL: Unable to allocate TLS key (%d)\n", errno
);
67 static DWORD tlsstr_key
= TLS_OUT_OF_INDEXES
;
68 static DWORD monitor_key
= TLS_OUT_OF_INDEXES
;
70 static void inittls(void) {
74 sprintf(name
, "pulse%d", (int)GetCurrentProcessId());
76 mutex
= CreateMutex(NULL
, FALSE
, name
);
78 fprintf(stderr
, __FILE__
": CRITICAL: Unable to create named mutex (%d)\n", (int)GetLastError());
82 WaitForSingleObject(mutex
, INFINITE
);
84 if (tlsstr_key
== TLS_OUT_OF_INDEXES
) {
85 tlsstr_key
= TlsAlloc();
86 monitor_key
= TlsAlloc();
87 if ((tlsstr_key
== TLS_OUT_OF_INDEXES
) || (monitor_key
== TLS_OUT_OF_INDEXES
)) {
88 fprintf(stderr
, __FILE__
": CRITICAL: Unable to allocate TLS key (%d)\n", (int)GetLastError());
99 * This is incredibly brain dead, but this is necessary when dealing with
100 * the hell that is Win32.
102 struct monitor_data
{
107 static DWORD WINAPI
monitor_thread(LPVOID param
) {
108 struct monitor_data
*data
;
110 data
= (struct monitor_data
*)param
;
113 WaitForSingleObject(data
->thread
, INFINITE
);
115 CloseHandle(data
->thread
);
116 pa_xfree(data
->data
);
122 static void start_monitor(void) {
124 struct monitor_data
*data
;
126 data
= pa_xnew(struct monitor_data
, 1);
129 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
130 GetCurrentProcess(), &data
->thread
, 0, FALSE
, DUPLICATE_SAME_ACCESS
);
132 thread
= CreateThread(NULL
, 0, monitor_thread
, data
, 0, NULL
);
135 TlsSetValue(monitor_key
, data
);
142 /* Unsafe, but we have no choice */
147 const char* pa_cstrerror(int errnum
) {
150 #ifdef HAVE_STRERROR_R
157 pthread_once(&cstrerror_once
, inittls
);
159 tlsstr
= pthread_getspecific(tlsstr_key
);
160 #elif defined(HAVE_WINDOWS_H)
162 struct monitor_data
*data
;
166 tlsstr
= TlsGetValue(tlsstr_key
);
169 data
= TlsGetValue(monitor_key
);
175 #ifdef HAVE_STRERROR_R
178 origbuf
= strerror_r(errnum
, errbuf
, sizeof(errbuf
));
182 if (strerror_r(errnum
, errbuf
, sizeof(errbuf
)) == 0) {
184 errbuf
[sizeof(errbuf
) - 1] = '\0';
190 /* This might not be thread safe, but we hope for the best */
191 origbuf
= strerror(errnum
);
194 tlsstr
= pa_locale_to_utf8(origbuf
);
196 fprintf(stderr
, "Unable to convert, filtering\n");
197 tlsstr
= pa_utf8_filter(origbuf
);
201 pthread_setspecific(tlsstr_key
, tlsstr
);
202 #elif defined(HAVE_WINDOWS_H)
203 TlsSetValue(tlsstr_key
, tlsstr
);