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);