File: | sal/osl/unx/thread.c |
Location: | line 229, column 5 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /************************************************************************* |
3 | * |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 | * |
6 | * Copyright 2000, 2010 Oracle and/or its affiliates. |
7 | * |
8 | * OpenOffice.org - a multi-platform office productivity suite |
9 | * |
10 | * This file is part of OpenOffice.org. |
11 | * |
12 | * OpenOffice.org is free software: you can redistribute it and/or modify |
13 | * it under the terms of the GNU Lesser General Public License version 3 |
14 | * only, as published by the Free Software Foundation. |
15 | * |
16 | * OpenOffice.org is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU Lesser General Public License version 3 for more details |
20 | * (a copy is included in the LICENSE file that accompanied this code). |
21 | * |
22 | * You should have received a copy of the GNU Lesser General Public License |
23 | * version 3 along with OpenOffice.org. If not, see |
24 | * <http://www.openoffice.org/license.html> |
25 | * for a copy of the LGPLv3 License. |
26 | * |
27 | ************************************************************************/ |
28 | |
29 | #include "system.h" |
30 | #include <string.h> |
31 | #if defined(OPENBSD) |
32 | #include <sched.h> |
33 | #endif |
34 | #include <osl/diagnose.h> |
35 | #include <osl/thread.h> |
36 | #include <osl/nlsupport.h> |
37 | #include <rtl/textenc.h> |
38 | #include <rtl/alloc.h> |
39 | #include <sal/macros.h> |
40 | #ifdef ANDROID |
41 | #include <jni.h> |
42 | #include <osl/detail/android-bootstrap.h> |
43 | #endif |
44 | |
45 | #if defined LINUX1 && ! defined __FreeBSD_kernel__ |
46 | #include <sys/prctl.h> |
47 | #ifndef PR_SET_NAME15 |
48 | #define PR_SET_NAME15 15 |
49 | #endif |
50 | #endif |
51 | |
52 | /**************************************************************************** |
53 | * @@@ TODO @@@ |
54 | * |
55 | * (1) 'osl_thread_priority_init_Impl()' |
56 | * - insane assumption that initializing caller is main thread |
57 | * - use _POSIX_THREAD_PRIORITY_SCHEDULING, not NO_PTHREAD_PRIORITY (?) |
58 | * - POSIX doesn't require defined prio's for SCHED_OTHER (!) |
59 | * - use SCHED_RR instead of SCHED_OTHER for defined behaviour (?) |
60 | * (2) 'oslThreadIdentifier' and '{insert|remove|lookup}ThreadId()' |
61 | * - cannot reliably be applied to 'alien' threads; |
62 | * - memory leak for 'alien' thread 'HashEntry's; |
63 | * - use 'PTHREAD_VALUE(pthread_t)' as identifier instead (?) |
64 | * - if yes, change 'oslThreadIdentifier' to 'intptr_t' or similar |
65 | * (3) 'oslSigAlarmHandler()' (#71232#) |
66 | * - [Under Solaris we get SIGALRM in e.g. pthread_join which terminates |
67 | * the process. So we initialize our signal handling module and do |
68 | * register a SIGALRM Handler which catches and ignores it] |
69 | * - should this still happen, 'signal.c' needs to be fixed instead. |
70 | * |
71 | ****************************************************************************/ |
72 | |
73 | /*****************************************************************************/ |
74 | /* Internal data structures and functions */ |
75 | /*****************************************************************************/ |
76 | |
77 | #define THREADIMPL_FLAGS_TERMINATE0x00001 0x00001 |
78 | #define THREADIMPL_FLAGS_STARTUP0x00002 0x00002 |
79 | #define THREADIMPL_FLAGS_SUSPENDED0x00004 0x00004 |
80 | #define THREADIMPL_FLAGS_ACTIVE0x00008 0x00008 |
81 | #define THREADIMPL_FLAGS_ATTACHED0x00010 0x00010 |
82 | #define THREADIMPL_FLAGS_DESTROYED0x00020 0x00020 |
83 | |
84 | typedef struct osl_thread_impl_st |
85 | { |
86 | pthread_t m_hThread; |
87 | sal_uInt16 m_Ident; /* @@@ see TODO @@@ */ |
88 | short m_Flags; |
89 | oslWorkerFunction m_WorkerFunction; |
90 | void* m_pData; |
91 | pthread_mutex_t m_Lock; |
92 | pthread_cond_t m_Cond; |
93 | } Thread_Impl; |
94 | |
95 | struct osl_thread_priority_st |
96 | { |
97 | int m_Highest; |
98 | int m_Above_Normal; |
99 | int m_Normal; |
100 | int m_Below_Normal; |
101 | int m_Lowest; |
102 | }; |
103 | |
104 | #define OSL_THREAD_PRIORITY_INITIALIZER{ 127, 96, 64, 32, 0 } { 127, 96, 64, 32, 0 } |
105 | static void osl_thread_priority_init_Impl (void); |
106 | |
107 | struct osl_thread_textencoding_st |
108 | { |
109 | pthread_key_t m_key; /* key to store thread local text encoding */ |
110 | rtl_TextEncoding m_default; /* the default text encoding */ |
111 | }; |
112 | |
113 | #define OSL_THREAD_TEXTENCODING_INITIALIZER{ 0, (((rtl_TextEncoding) 0)) } { 0, RTL_TEXTENCODING_DONTKNOW(((rtl_TextEncoding) 0)) } |
114 | static void osl_thread_textencoding_init_Impl (void); |
115 | |
116 | struct osl_thread_global_st |
117 | { |
118 | pthread_once_t m_once; |
119 | struct osl_thread_priority_st m_priority; |
120 | struct osl_thread_textencoding_st m_textencoding; |
121 | }; |
122 | |
123 | static struct osl_thread_global_st g_thread = |
124 | { |
125 | PTHREAD_ONCE_INIT0, |
126 | OSL_THREAD_PRIORITY_INITIALIZER{ 127, 96, 64, 32, 0 }, |
127 | OSL_THREAD_TEXTENCODING_INITIALIZER{ 0, (((rtl_TextEncoding) 0)) } |
128 | }; |
129 | |
130 | static void osl_thread_init_Impl (void); |
131 | |
132 | static Thread_Impl* osl_thread_construct_Impl (void); |
133 | static void osl_thread_destruct_Impl (Thread_Impl ** ppImpl); |
134 | |
135 | static void* osl_thread_start_Impl (void * pData); |
136 | static void osl_thread_cleanup_Impl (Thread_Impl * pImpl); |
137 | |
138 | static oslThread osl_thread_create_Impl ( |
139 | oslWorkerFunction pWorker, void * pThreadData, short nFlags); |
140 | |
141 | /* @@@ see TODO @@@ */ |
142 | static sal_uInt16 insertThreadId (pthread_t hThread); |
143 | static sal_uInt16 lookupThreadId (pthread_t hThread); |
144 | static void removeThreadId (pthread_t hThread); |
145 | |
146 | /*****************************************************************************/ |
147 | /* osl_thread_init_Impl */ |
148 | /*****************************************************************************/ |
149 | static void osl_thread_init_Impl (void) |
150 | { |
151 | osl_thread_priority_init_Impl(); |
152 | osl_thread_textencoding_init_Impl(); |
153 | } |
154 | |
155 | /*****************************************************************************/ |
156 | /* osl_thread_construct_Impl */ |
157 | /*****************************************************************************/ |
158 | Thread_Impl* osl_thread_construct_Impl (void) |
159 | { |
160 | Thread_Impl* pImpl = malloc (sizeof(Thread_Impl)); |
161 | if (pImpl) |
162 | { |
163 | memset (pImpl, 0, sizeof(Thread_Impl)); |
164 | |
165 | pthread_mutex_init (&(pImpl->m_Lock), PTHREAD_MUTEXATTR_DEFAULT((void*)0)); |
166 | pthread_cond_init (&(pImpl->m_Cond), PTHREAD_CONDATTR_DEFAULT((void*)0)); |
167 | } |
168 | return (pImpl); |
169 | } |
170 | |
171 | /*****************************************************************************/ |
172 | /* osl_thread_destruct_Impl */ |
173 | /*****************************************************************************/ |
174 | static void osl_thread_destruct_Impl (Thread_Impl ** ppImpl) |
175 | { |
176 | OSL_ASSERT(ppImpl)do { if (((sal_Bool)1) && (!(ppImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "176" ": "), "OSL_ASSERT: %s", "ppImpl"); } } while (((sal_Bool )0)); |
177 | if (*ppImpl) |
178 | { |
179 | pthread_cond_destroy (&((*ppImpl)->m_Cond)); |
180 | pthread_mutex_destroy (&((*ppImpl)->m_Lock)); |
181 | |
182 | free (*ppImpl); |
183 | (*ppImpl) = 0; |
184 | } |
185 | } |
186 | |
187 | /*****************************************************************************/ |
188 | /* osl_thread_cleanup_Impl */ |
189 | /*****************************************************************************/ |
190 | static void osl_thread_cleanup_Impl (Thread_Impl * pImpl) |
191 | { |
192 | pthread_t thread; |
193 | int attached; |
194 | int destroyed; |
195 | |
196 | pthread_mutex_lock (&(pImpl->m_Lock)); |
197 | |
198 | thread = pImpl->m_hThread; |
199 | attached = (pImpl->m_Flags & THREADIMPL_FLAGS_ATTACHED0x00010) != 0; |
200 | destroyed = (pImpl->m_Flags & THREADIMPL_FLAGS_DESTROYED0x00020) != 0; |
201 | pImpl->m_Flags &= ~(THREADIMPL_FLAGS_ACTIVE0x00008 | THREADIMPL_FLAGS_ATTACHED0x00010); |
202 | |
203 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
204 | |
205 | /* release oslThreadIdentifier @@@ see TODO @@@ */ |
206 | removeThreadId (thread); |
207 | |
208 | if (attached) |
209 | { |
210 | pthread_detach (thread); |
211 | } |
212 | |
213 | if (destroyed) |
214 | { |
215 | osl_thread_destruct_Impl (&pImpl); |
216 | } |
217 | } |
218 | |
219 | /*****************************************************************************/ |
220 | /* osl_thread_start_Impl */ |
221 | /*****************************************************************************/ |
222 | static void* osl_thread_start_Impl (void* pData) |
223 | { |
224 | int terminate; |
225 | Thread_Impl* pImpl= (Thread_Impl*)pData; |
226 | |
227 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "227" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
228 | |
229 | pthread_mutex_lock (&(pImpl->m_Lock)); |
Null pointer passed as an argument to a 'nonnull' parameter | |
230 | |
231 | /* request oslThreadIdentifier @@@ see TODO @@@ */ |
232 | pImpl->m_Ident = insertThreadId (pImpl->m_hThread); |
233 | |
234 | /* signal change from STARTUP to ACTIVE state */ |
235 | pImpl->m_Flags &= ~THREADIMPL_FLAGS_STARTUP0x00002; |
236 | pImpl->m_Flags |= THREADIMPL_FLAGS_ACTIVE0x00008; |
237 | pthread_cond_signal (&(pImpl->m_Cond)); |
238 | |
239 | /* Check if thread is started in SUSPENDED state */ |
240 | while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED0x00004) |
241 | { |
242 | /* wait until SUSPENDED flag is cleared */ |
243 | pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock)); |
244 | } |
245 | |
246 | /* check for SUSPENDED to TERMINATE state change */ |
247 | terminate = ((pImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE0x00001) > 0); |
248 | |
249 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
250 | |
251 | if (!terminate) |
252 | { |
253 | #ifdef ANDROID |
254 | { |
255 | JNIEnv* env = 0; |
256 | int res = (*lo_get_javavm())->AttachCurrentThread(lo_get_javavm(), &env, NULL((void*)0)); // res == 0 |
257 | fprintf (stderrstderr, "new sal thread started and attached %d!\n", res); |
258 | } |
259 | #endif |
260 | /* call worker function */ |
261 | pImpl->m_WorkerFunction(pImpl->m_pData); |
262 | |
263 | #ifdef ANDROID |
264 | { |
265 | int res = (*lo_get_javavm())->DetachCurrentThread(lo_get_javavm()); |
266 | fprintf (stderrstderr, "detached finished sal thread %d!\n", res); |
267 | } |
268 | #endif |
269 | } |
270 | |
271 | osl_thread_cleanup_Impl (pImpl); |
272 | return (0); |
273 | } |
274 | |
275 | /*****************************************************************************/ |
276 | /* osl_thread_create_Impl */ |
277 | /*****************************************************************************/ |
278 | static oslThread osl_thread_create_Impl ( |
279 | oslWorkerFunction pWorker, |
280 | void* pThreadData, |
281 | short nFlags) |
282 | { |
283 | Thread_Impl* pImpl; |
284 | #if defined(OPENBSD) |
285 | pthread_attr_t attr; |
286 | #endif |
287 | int nRet=0; |
288 | |
289 | pImpl = osl_thread_construct_Impl(); |
290 | if (!pImpl) |
291 | return (0); /* ENOMEM */ |
292 | |
293 | pImpl->m_WorkerFunction = pWorker; |
294 | pImpl->m_pData = pThreadData; |
295 | pImpl->m_Flags = nFlags | THREADIMPL_FLAGS_STARTUP0x00002; |
296 | |
297 | pthread_mutex_lock (&(pImpl->m_Lock)); |
298 | |
299 | #if defined(OPENBSD) |
300 | if (pthread_attr_init(&attr) != 0) |
301 | return (0); |
302 | |
303 | if (pthread_attr_setstacksize(&attr, 262144) != 0) { |
304 | pthread_attr_destroy(&attr); |
305 | return (0); |
306 | } |
307 | #endif |
308 | |
309 | if ((nRet = pthread_create ( |
310 | &(pImpl->m_hThread), |
311 | #if defined(OPENBSD) |
312 | &attr, |
313 | #else |
314 | PTHREAD_ATTR_DEFAULT((void*)0), |
315 | #endif |
316 | osl_thread_start_Impl, |
317 | (void*)(pImpl))) != 0) |
318 | { |
319 | OSL_TRACE("osl_thread_create_Impl(): errno: %d, %s\n",do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "320" ": "), "osl_thread_create_Impl(): errno: %d, %s\n" , nRet, strerror(nRet)); } } while (((sal_Bool)0)) |
320 | nRet, strerror(nRet))do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "320" ": "), "osl_thread_create_Impl(): errno: %d, %s\n" , nRet, strerror(nRet)); } } while (((sal_Bool)0)); |
321 | |
322 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
323 | osl_thread_destruct_Impl (&pImpl); |
324 | |
325 | return (0); |
326 | } |
327 | |
328 | #if defined(OPENBSD) |
329 | pthread_attr_destroy(&attr); |
330 | #endif |
331 | |
332 | /* wait for change from STARTUP to ACTIVE state */ |
333 | while (pImpl->m_Flags & THREADIMPL_FLAGS_STARTUP0x00002) |
334 | { |
335 | /* wait until STARTUP flag is cleared */ |
336 | pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock)); |
337 | } |
338 | |
339 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
340 | |
341 | return ((oslThread)(pImpl)); |
342 | } |
343 | |
344 | /*****************************************************************************/ |
345 | /* osl_createThread */ |
346 | /*****************************************************************************/ |
347 | oslThread osl_createThread ( |
348 | oslWorkerFunction pWorker, |
349 | void * pThreadData) |
350 | { |
351 | return osl_thread_create_Impl ( |
352 | pWorker, |
353 | pThreadData, |
354 | THREADIMPL_FLAGS_ATTACHED0x00010); |
355 | } |
356 | |
357 | /*****************************************************************************/ |
358 | /* osl_createSuspendedThread */ |
359 | /*****************************************************************************/ |
360 | oslThread osl_createSuspendedThread ( |
361 | oslWorkerFunction pWorker, |
362 | void * pThreadData) |
363 | { |
364 | return osl_thread_create_Impl ( |
365 | pWorker, |
366 | pThreadData, |
367 | THREADIMPL_FLAGS_ATTACHED0x00010 | |
368 | THREADIMPL_FLAGS_SUSPENDED0x00004 ); |
369 | } |
370 | |
371 | /*****************************************************************************/ |
372 | /* osl_destroyThread */ |
373 | /*****************************************************************************/ |
374 | void SAL_CALL osl_destroyThread(oslThread Thread) |
375 | { |
376 | if (Thread != NULL((void*)0)) { |
377 | Thread_Impl * impl = (Thread_Impl *) Thread; |
378 | int active; |
379 | pthread_mutex_lock(&impl->m_Lock); |
380 | active = (impl->m_Flags & THREADIMPL_FLAGS_ACTIVE0x00008) != 0; |
381 | impl->m_Flags |= THREADIMPL_FLAGS_DESTROYED0x00020; |
382 | pthread_mutex_unlock(&impl->m_Lock); |
383 | if (!active) { |
384 | osl_thread_destruct_Impl(&impl); |
385 | } |
386 | } |
387 | } |
388 | |
389 | /*****************************************************************************/ |
390 | /* osl_resumeThread */ |
391 | /*****************************************************************************/ |
392 | void SAL_CALL osl_resumeThread(oslThread Thread) |
393 | { |
394 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
395 | |
396 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "396" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
397 | if (!pImpl) |
398 | return; /* EINVAL */ |
399 | |
400 | pthread_mutex_lock (&(pImpl->m_Lock)); |
401 | |
402 | if (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED0x00004) |
403 | { |
404 | /* clear SUSPENDED flag */ |
405 | pImpl->m_Flags &= ~THREADIMPL_FLAGS_SUSPENDED0x00004; |
406 | pthread_cond_signal (&(pImpl->m_Cond)); |
407 | } |
408 | |
409 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
410 | } |
411 | |
412 | /*****************************************************************************/ |
413 | /* osl_suspendThread */ |
414 | /*****************************************************************************/ |
415 | void SAL_CALL osl_suspendThread(oslThread Thread) |
416 | { |
417 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
418 | |
419 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "419" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
420 | if (!pImpl) |
421 | return; /* EINVAL */ |
422 | |
423 | pthread_mutex_lock (&(pImpl->m_Lock)); |
424 | |
425 | pImpl->m_Flags |= THREADIMPL_FLAGS_SUSPENDED0x00004; |
426 | |
427 | if (pthread_equal (pthread_self(), pImpl->m_hThread)) |
428 | { |
429 | /* self suspend */ |
430 | while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED0x00004) |
431 | { |
432 | /* wait until SUSPENDED flag is cleared */ |
433 | pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock)); |
434 | } |
435 | } |
436 | |
437 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
438 | } |
439 | |
440 | /*****************************************************************************/ |
441 | /* osl_isThreadRunning */ |
442 | /*****************************************************************************/ |
443 | sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread) |
444 | { |
445 | sal_Bool active; |
446 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
447 | |
448 | if (!pImpl) |
449 | return sal_False((sal_Bool)0); |
450 | |
451 | pthread_mutex_lock (&(pImpl->m_Lock)); |
452 | active = ((pImpl->m_Flags & THREADIMPL_FLAGS_ACTIVE0x00008) > 0); |
453 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
454 | |
455 | return (active); |
456 | } |
457 | |
458 | /*****************************************************************************/ |
459 | /* osl_joinWithThread */ |
460 | /*****************************************************************************/ |
461 | void SAL_CALL osl_joinWithThread(oslThread Thread) |
462 | { |
463 | pthread_t thread; |
464 | int attached; |
465 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
466 | |
467 | if (!pImpl) |
468 | return; |
469 | |
470 | pthread_mutex_lock (&(pImpl->m_Lock)); |
471 | |
472 | if (pthread_equal (pthread_self(), pImpl->m_hThread)) |
473 | { |
474 | /* self join */ |
475 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
476 | return; /* EDEADLK */ |
477 | } |
478 | |
479 | thread = pImpl->m_hThread; |
480 | attached = ((pImpl->m_Flags & THREADIMPL_FLAGS_ATTACHED0x00010) > 0); |
481 | pImpl->m_Flags &= ~THREADIMPL_FLAGS_ATTACHED0x00010; |
482 | |
483 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
484 | |
485 | if (attached) |
486 | { |
487 | pthread_join (thread, NULL((void*)0)); |
488 | } |
489 | } |
490 | |
491 | /*****************************************************************************/ |
492 | /* osl_terminateThread */ |
493 | /*****************************************************************************/ |
494 | void SAL_CALL osl_terminateThread(oslThread Thread) |
495 | { |
496 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
497 | |
498 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "498" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
499 | if (!pImpl) |
500 | return; /* EINVAL */ |
501 | |
502 | pthread_mutex_lock (&(pImpl->m_Lock)); |
503 | |
504 | if (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED0x00004) |
505 | { |
506 | /* clear SUSPENDED flag */ |
507 | pImpl->m_Flags &= ~THREADIMPL_FLAGS_SUSPENDED0x00004; |
508 | pthread_cond_signal (&(pImpl->m_Cond)); |
509 | } |
510 | |
511 | pImpl->m_Flags |= THREADIMPL_FLAGS_TERMINATE0x00001; |
512 | |
513 | pthread_mutex_unlock (&(pImpl->m_Lock)); |
514 | } |
515 | |
516 | /*****************************************************************************/ |
517 | /* osl_scheduleThread */ |
518 | /*****************************************************************************/ |
519 | sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread) |
520 | { |
521 | int terminate; |
522 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
523 | |
524 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "524" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
525 | if (!pImpl) |
526 | return sal_False((sal_Bool)0); /* EINVAL */ |
527 | |
528 | OSL_ASSERT(pthread_equal (pthread_self(), pImpl->m_hThread))do { if (((sal_Bool)1) && (!(pthread_equal (pthread_self (), pImpl->m_hThread)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "528" ": "), "OSL_ASSERT: %s", "pthread_equal (pthread_self(), pImpl->m_hThread)" ); } } while (((sal_Bool)0)); |
529 | if (!(pthread_equal (pthread_self(), pImpl->m_hThread))) |
530 | return sal_False((sal_Bool)0); /* EINVAL */ |
531 | |
532 | pthread_mutex_lock (&(pImpl->m_Lock)); |
533 | |
534 | while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED0x00004) |
535 | { |
536 | /* wait until SUSPENDED flag is cleared */ |
537 | pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock)); |
538 | } |
539 | |
540 | terminate = ((pImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE0x00001) > 0); |
541 | |
542 | pthread_mutex_unlock(&(pImpl->m_Lock)); |
543 | |
544 | return (terminate == 0); |
545 | } |
546 | |
547 | /*****************************************************************************/ |
548 | /* osl_waitThread */ |
549 | /*****************************************************************************/ |
550 | void SAL_CALL osl_waitThread(const TimeValue* pDelay) |
551 | { |
552 | if (pDelay) |
553 | { |
554 | struct timespec delay; |
555 | |
556 | SET_TIMESPEC(delay, pDelay->Seconds, pDelay->Nanosec)delay . tv_sec = (pDelay->Seconds); delay . tv_nsec = (pDelay ->Nanosec); delay . tv_sec += delay . tv_nsec / 1000000000 ; delay . tv_nsec %= 1000000000;;; |
557 | |
558 | SLEEP_TIMESPEC(delay)nanosleep(&delay, 0); |
559 | } |
560 | } |
561 | |
562 | /*****************************************************************************/ |
563 | /* osl_yieldThread */ |
564 | /* |
565 | Note that POSIX scheduling _really_ requires threads to call this |
566 | functions, since a thread only reschedules to other thread, when |
567 | it blocks (sleep, blocking I/O) OR calls sched_yield(). |
568 | */ |
569 | /*****************************************************************************/ |
570 | void SAL_CALL osl_yieldThread() |
571 | { |
572 | sched_yield(); |
573 | } |
574 | |
575 | void SAL_CALL osl_setThreadName(char const * name) { |
576 | #if defined LINUX1 && ! defined __FreeBSD_kernel__ |
577 | if (prctl(PR_SET_NAME15, (unsigned long) name, 0, 0, 0) != 0) { |
578 | OSL_TRACE(do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "580" ": "), "%s prctl(PR_SET_NAME) failed with errno %d" , "/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "579" ": ", (*__errno_location ())); } } while (((sal_Bool)0)) |
579 | "%s prctl(PR_SET_NAME) failed with errno %d", OSL_LOG_PREFIX,do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "580" ": "), "%s prctl(PR_SET_NAME) failed with errno %d" , "/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "579" ": ", (*__errno_location ())); } } while (((sal_Bool)0)) |
580 | errno)do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "580" ": "), "%s prctl(PR_SET_NAME) failed with errno %d" , "/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "579" ": ", (*__errno_location ())); } } while (((sal_Bool)0)); |
581 | } |
582 | #else |
583 | (void) name; |
584 | #endif |
585 | } |
586 | |
587 | /*****************************************************************************/ |
588 | /* osl_getThreadIdentifier @@@ see TODO @@@ */ |
589 | /*****************************************************************************/ |
590 | |
591 | #define HASHID(x)((unsigned int)(x) % HashSize) ((unsigned int)PTHREAD_VALUE(x)(x) % HashSize) |
592 | |
593 | typedef struct _HashEntry |
594 | { |
595 | pthread_t Handle; |
596 | sal_uInt16 Ident; |
597 | struct _HashEntry *Next; |
598 | } HashEntry; |
599 | |
600 | static HashEntry* HashTable[31]; |
601 | static int HashSize = SAL_N_ELEMENTS(HashTable)(sizeof (HashTable) / sizeof ((HashTable)[0])); |
602 | |
603 | static pthread_mutex_t HashLock = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, { 0 } } }; |
604 | |
605 | static sal_uInt16 LastIdent = 0; |
606 | |
607 | static sal_uInt16 lookupThreadId (pthread_t hThread) |
608 | { |
609 | HashEntry *pEntry; |
610 | |
611 | pthread_mutex_lock(&HashLock); |
612 | |
613 | pEntry = HashTable[HASHID(hThread)((unsigned int)(hThread) % HashSize)]; |
614 | while (pEntry != NULL((void*)0)) |
615 | { |
616 | if (pthread_equal(pEntry->Handle, hThread)) |
617 | { |
618 | pthread_mutex_unlock(&HashLock); |
619 | return (pEntry->Ident); |
620 | } |
621 | pEntry = pEntry->Next; |
622 | } |
623 | |
624 | pthread_mutex_unlock(&HashLock); |
625 | |
626 | return (0); |
627 | } |
628 | |
629 | static sal_uInt16 insertThreadId (pthread_t hThread) |
630 | { |
631 | HashEntry *pEntry, *pInsert = NULL((void*)0); |
632 | |
633 | pthread_mutex_lock(&HashLock); |
634 | |
635 | pEntry = HashTable[HASHID(hThread)((unsigned int)(hThread) % HashSize)]; |
636 | |
637 | while (pEntry != NULL((void*)0)) |
638 | { |
639 | if (pthread_equal(pEntry->Handle, hThread)) |
640 | break; |
641 | |
642 | pInsert = pEntry; |
643 | pEntry = pEntry->Next; |
644 | } |
645 | |
646 | if (pEntry == NULL((void*)0)) |
647 | { |
648 | pEntry = (HashEntry*) calloc(sizeof(HashEntry), 1); |
649 | |
650 | pEntry->Handle = hThread; |
651 | |
652 | ++ LastIdent; |
653 | |
654 | if ( LastIdent == 0 ) |
655 | LastIdent = 1; |
656 | |
657 | pEntry->Ident = LastIdent; |
658 | |
659 | if (pInsert) |
660 | pInsert->Next = pEntry; |
661 | else |
662 | HashTable[HASHID(hThread)((unsigned int)(hThread) % HashSize)] = pEntry; |
663 | } |
664 | |
665 | pthread_mutex_unlock(&HashLock); |
666 | |
667 | return (pEntry->Ident); |
668 | } |
669 | |
670 | static void removeThreadId (pthread_t hThread) |
671 | { |
672 | HashEntry *pEntry, *pRemove = NULL((void*)0); |
673 | |
674 | pthread_mutex_lock(&HashLock); |
675 | |
676 | pEntry = HashTable[HASHID(hThread)((unsigned int)(hThread) % HashSize)]; |
677 | while (pEntry != NULL((void*)0)) |
678 | { |
679 | if (pthread_equal(pEntry->Handle, hThread)) |
680 | break; |
681 | |
682 | pRemove = pEntry; |
683 | pEntry = pEntry->Next; |
684 | } |
685 | |
686 | if (pEntry != NULL((void*)0)) |
687 | { |
688 | if (pRemove) |
689 | pRemove->Next = pEntry->Next; |
690 | else |
691 | HashTable[HASHID(hThread)((unsigned int)(hThread) % HashSize)] = pEntry->Next; |
692 | |
693 | free(pEntry); |
694 | } |
695 | |
696 | pthread_mutex_unlock(&HashLock); |
697 | } |
698 | |
699 | oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread) |
700 | { |
701 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
702 | sal_uInt16 Ident; |
703 | |
704 | if (pImpl) |
705 | Ident = pImpl->m_Ident; |
706 | else |
707 | { |
708 | /* current thread */ |
709 | pthread_t current = pthread_self(); |
710 | |
711 | Ident = lookupThreadId (current); |
712 | if (Ident == 0) |
713 | /* @@@ see TODO: alien pthread_self() @@@ */ |
714 | Ident = insertThreadId (current); |
715 | } |
716 | |
717 | return ((oslThreadIdentifier)(Ident)); |
718 | } |
719 | |
720 | /***************************************************************************** |
721 | @@@ see TODO @@@ |
722 | osl_thread_priority_init_Impl |
723 | |
724 | set the base-priority of the main-thread to |
725 | oslThreadPriorityNormal (64) since 0 (lowest) is |
726 | the system default. This behaviour collides with |
727 | our enum-priority definition (highest..normal..lowest). |
728 | A normaluser will expect the main-thread of an app. |
729 | to have the "normal" priority. |
730 | |
731 | *****************************************************************************/ |
732 | static void osl_thread_priority_init_Impl (void) |
733 | { |
734 | #ifndef NO_PTHREAD_PRIORITY |
735 | struct sched_param param; |
736 | int policy=0; |
737 | int nRet=0; |
738 | |
739 | /* @@@ see TODO: calling thread may not be main thread @@@ */ |
740 | |
741 | if ((nRet = pthread_getschedparam(pthread_self(), &policy, ¶m)) != 0) |
742 | { |
743 | OSL_TRACE("failed to get priority of thread [%s]",strerror(nRet))do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "743" ": "), "failed to get priority of thread [%s]",strerror (nRet)); } } while (((sal_Bool)0)); |
744 | return; |
745 | } |
746 | |
747 | #if defined (SOLARIS) |
748 | if ( policy >= _SCHED_NEXT) |
749 | { |
750 | /* mfe: pthread_getschedparam on Solaris has a possible Bug */ |
751 | /* one gets 959917873 as the policy */ |
752 | /* so set the policy to a default one */ |
753 | policy=SCHED_OTHER0; |
754 | } |
755 | #endif /* SOLARIS */ |
756 | |
757 | if ((nRet = sched_get_priority_min(policy) ) != -1) |
758 | { |
759 | OSL_TRACE("Min Prioriy for policy '%i' == '%i'",policy,nRet)do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "759" ": "), "Min Prioriy for policy '%i' == '%i'",policy ,nRet); } } while (((sal_Bool)0)); |
760 | g_thread.m_priority.m_Lowest=nRet; |
761 | } |
762 | #if OSL_DEBUG_LEVEL1 > 1 |
763 | else |
764 | { |
765 | fprintf(stderrstderr,"failed to get min sched param [%s]\n",strerror(errno(*__errno_location ()))); |
766 | } |
767 | #endif /* OSL_DEBUG_LEVEL */ |
768 | |
769 | if ((nRet = sched_get_priority_max(policy) ) != -1) |
770 | { |
771 | OSL_TRACE("Max Prioriy for policy '%i' == '%i'",policy,nRet)do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "771" ": "), "Max Prioriy for policy '%i' == '%i'",policy ,nRet); } } while (((sal_Bool)0)); |
772 | g_thread.m_priority.m_Highest=nRet; |
773 | } |
774 | #if OSL_DEBUG_LEVEL1 > 1 |
775 | else |
776 | { |
777 | fprintf(stderrstderr,"failed to get max sched param [%s]\n",strerror(errno(*__errno_location ()))); |
778 | } |
779 | #endif /* OSL_DEBUG_LEVEL */ |
780 | |
781 | g_thread.m_priority.m_Normal = |
782 | (g_thread.m_priority.m_Lowest + g_thread.m_priority.m_Highest) / 2; |
783 | g_thread.m_priority.m_Below_Normal = |
784 | (g_thread.m_priority.m_Lowest + g_thread.m_priority.m_Normal) / 2; |
785 | g_thread.m_priority.m_Above_Normal = |
786 | (g_thread.m_priority.m_Normal + g_thread.m_priority.m_Highest) / 2; |
787 | |
788 | /* @@@ set prio of calling (not main) thread (?) @@@ */ |
789 | |
790 | param.sched_priority__sched_priority= g_thread.m_priority.m_Normal; |
791 | |
792 | if ((nRet = pthread_setschedparam(pthread_self(), policy, ¶m)) != 0) |
793 | { |
794 | OSL_TRACE("failed to change base priority of thread [%s]",strerror(nRet))do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "794" ": "), "failed to change base priority of thread [%s]" ,strerror(nRet)); } } while (((sal_Bool)0)); |
795 | OSL_TRACE("Thread ID '%i', Policy '%i', Priority '%i'\n",pthread_self(),policy,param.sched_priority)do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "795" ": "), "Thread ID '%i', Policy '%i', Priority '%i'\n" ,pthread_self(),policy,param.__sched_priority); } } while ((( sal_Bool)0)); |
796 | } |
797 | |
798 | #endif /* NO_PTHREAD_PRIORITY */ |
799 | } |
800 | |
801 | /*****************************************************************************/ |
802 | /* osl_setThreadPriority */ |
803 | /* |
804 | Impl-Notes: contrary to solaris-docu, which claims |
805 | valid priority-levels from 0 .. INT_MAX, only the |
806 | range 0..127 is accepted. (0 lowest, 127 highest) |
807 | */ |
808 | /*****************************************************************************/ |
809 | void SAL_CALL osl_setThreadPriority ( |
810 | oslThread Thread, |
811 | oslThreadPriority Priority) |
812 | { |
813 | #ifndef NO_PTHREAD_PRIORITY |
814 | |
815 | struct sched_param Param; |
816 | int policy; |
817 | int nRet; |
818 | |
819 | #endif /* NO_PTHREAD_PRIORITY */ |
820 | |
821 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
822 | |
823 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "823" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
824 | if (!pImpl) |
825 | return; /* EINVAL */ |
826 | |
827 | #ifdef NO_PTHREAD_PRIORITY |
828 | (void) Priority; /* unused */ |
829 | #else /* NO_PTHREAD_PRIORITY */ |
830 | |
831 | if (pthread_getschedparam(pImpl->m_hThread, &policy, &Param) != 0) |
832 | return; /* ESRCH */ |
833 | |
834 | #if defined (SOLARIS) |
835 | if ( policy >= _SCHED_NEXT) |
836 | { |
837 | /* mfe: pthread_getschedparam on Solaris has a possible Bug */ |
838 | /* one gets 959917873 as the policy */ |
839 | /* so set the policy to a default one */ |
840 | policy=SCHED_OTHER0; |
841 | } |
842 | #endif /* SOLARIS */ |
843 | |
844 | pthread_once (&(g_thread.m_once), osl_thread_init_Impl); |
845 | |
846 | switch(Priority) |
847 | { |
848 | case osl_Thread_PriorityHighest: |
849 | Param.sched_priority__sched_priority= g_thread.m_priority.m_Highest; |
850 | break; |
851 | |
852 | case osl_Thread_PriorityAboveNormal: |
853 | Param.sched_priority__sched_priority= g_thread.m_priority.m_Above_Normal; |
854 | break; |
855 | |
856 | case osl_Thread_PriorityNormal: |
857 | Param.sched_priority__sched_priority= g_thread.m_priority.m_Normal; |
858 | break; |
859 | |
860 | case osl_Thread_PriorityBelowNormal: |
861 | Param.sched_priority__sched_priority= g_thread.m_priority.m_Below_Normal; |
862 | break; |
863 | |
864 | case osl_Thread_PriorityLowest: |
865 | Param.sched_priority__sched_priority= g_thread.m_priority.m_Lowest; |
866 | break; |
867 | |
868 | case osl_Thread_PriorityUnknown: |
869 | OSL_ASSERT(sal_False)do { if (((sal_Bool)1) && (!(((sal_Bool)0)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "869" ": "), "OSL_ASSERT: %s", "sal_False"); } } while ( ((sal_Bool)0)); /* only fools try this...*/ |
870 | |
871 | /* let release-version behave friendly */ |
872 | return; |
873 | |
874 | default: |
875 | /* enum expanded, but forgotten here...*/ |
876 | OSL_ENSURE(sal_False,"osl_setThreadPriority : unknown priority\n")do { if (((sal_Bool)1) && (!(((sal_Bool)0)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "876" ": "), "%s", "osl_setThreadPriority : unknown priority\n" ); } } while (((sal_Bool)0)); |
877 | |
878 | /* let release-version behave friendly */ |
879 | return; |
880 | } |
881 | |
882 | if ((nRet = pthread_setschedparam(pImpl->m_hThread, policy, &Param)) != 0) |
883 | { |
884 | OSL_TRACE("failed to change thread priority [%s]",strerror(nRet))do { if (((sal_Bool)1) && (1 > 0)) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "884" ": "), "failed to change thread priority [%s]",strerror (nRet)); } } while (((sal_Bool)0)); |
885 | } |
886 | |
887 | #endif /* NO_PTHREAD_PRIORITY */ |
888 | } |
889 | |
890 | /*****************************************************************************/ |
891 | /* osl_getThreadPriority */ |
892 | /*****************************************************************************/ |
893 | oslThreadPriority SAL_CALL osl_getThreadPriority(const oslThread Thread) |
894 | { |
895 | #ifndef NO_PTHREAD_PRIORITY |
896 | |
897 | struct sched_param Param; |
898 | int Policy; |
899 | |
900 | #endif /* NO_PTHREAD_PRIORITY */ |
901 | |
902 | oslThreadPriority Priority = osl_Thread_PriorityNormal; |
903 | Thread_Impl* pImpl= (Thread_Impl*)Thread; |
904 | |
905 | OSL_ASSERT(pImpl)do { if (((sal_Bool)1) && (!(pImpl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "905" ": "), "OSL_ASSERT: %s", "pImpl"); } } while (((sal_Bool )0)); |
906 | if (!pImpl) |
907 | return osl_Thread_PriorityUnknown; /* EINVAL */ |
908 | |
909 | #ifndef NO_PTHREAD_PRIORITY |
910 | |
911 | if (pthread_getschedparam(pImpl->m_hThread, &Policy, &Param) != 0) |
912 | return osl_Thread_PriorityUnknown; /* ESRCH */ |
913 | |
914 | pthread_once (&(g_thread.m_once), osl_thread_init_Impl); |
915 | |
916 | /* map pthread priority to enum */ |
917 | if (Param.sched_priority__sched_priority==g_thread.m_priority.m_Highest) |
918 | { |
919 | /* 127 - highest */ |
920 | Priority= osl_Thread_PriorityHighest; |
921 | } |
922 | else if (Param.sched_priority__sched_priority > g_thread.m_priority.m_Normal) |
923 | { |
924 | /* 65..126 - above normal */ |
925 | Priority= osl_Thread_PriorityAboveNormal; |
926 | } |
927 | else if (Param.sched_priority__sched_priority == g_thread.m_priority.m_Normal) |
928 | { |
929 | /* normal */ |
930 | Priority= osl_Thread_PriorityNormal; |
931 | } |
932 | else if (Param.sched_priority__sched_priority > g_thread.m_priority.m_Lowest) |
933 | { |
934 | /* 63..1 -below normal */ |
935 | Priority= osl_Thread_PriorityBelowNormal; |
936 | } |
937 | else if (Param.sched_priority__sched_priority == g_thread.m_priority.m_Lowest) |
938 | { |
939 | /* 0 - lowest */ |
940 | Priority= osl_Thread_PriorityLowest; |
941 | } |
942 | else |
943 | { |
944 | /* unknown */ |
945 | Priority= osl_Thread_PriorityUnknown; |
946 | } |
947 | |
948 | #endif /* NO_PTHREAD_PRIORITY */ |
949 | |
950 | return Priority; |
951 | } |
952 | |
953 | typedef struct _wrapper_pthread_key |
954 | { |
955 | pthread_key_t m_key; |
956 | oslThreadKeyCallbackFunction pfnCallback; |
957 | } wrapper_pthread_key; |
958 | |
959 | /*****************************************************************************/ |
960 | /* osl_createThreadKey */ |
961 | /*****************************************************************************/ |
962 | oslThreadKey SAL_CALL osl_createThreadKey( oslThreadKeyCallbackFunction pCallback ) |
963 | { |
964 | wrapper_pthread_key *pKey = (wrapper_pthread_key*)rtl_allocateMemory(sizeof(wrapper_pthread_key)); |
965 | |
966 | if (pKey) |
967 | { |
968 | pKey->pfnCallback = pCallback; |
969 | |
970 | if (pthread_key_create(&(pKey->m_key), pKey->pfnCallback) != 0) |
971 | { |
972 | rtl_freeMemory(pKey); |
973 | pKey = 0; |
974 | } |
975 | } |
976 | |
977 | return ((oslThreadKey)pKey); |
978 | } |
979 | |
980 | /*****************************************************************************/ |
981 | /* osl_destroyThreadKey */ |
982 | /*****************************************************************************/ |
983 | void SAL_CALL osl_destroyThreadKey(oslThreadKey Key) |
984 | { |
985 | wrapper_pthread_key *pKey = (wrapper_pthread_key*)Key; |
986 | if (pKey) |
987 | { |
988 | pthread_key_delete(pKey->m_key); |
989 | rtl_freeMemory(pKey); |
990 | } |
991 | } |
992 | |
993 | /*****************************************************************************/ |
994 | /* osl_getThreadKeyData */ |
995 | /*****************************************************************************/ |
996 | void* SAL_CALL osl_getThreadKeyData(oslThreadKey Key) |
997 | { |
998 | wrapper_pthread_key *pKey = (wrapper_pthread_key*)Key; |
999 | return pKey ? pthread_getspecific(pKey->m_key) : NULL((void*)0); |
1000 | } |
1001 | |
1002 | /*****************************************************************************/ |
1003 | /* osl_setThreadKeyData */ |
1004 | /*****************************************************************************/ |
1005 | sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData) |
1006 | { |
1007 | sal_Bool bRet; |
1008 | void *pOldData = NULL((void*)0); |
1009 | wrapper_pthread_key *pKey = (wrapper_pthread_key*)Key; |
1010 | if (!pKey) |
1011 | return sal_False((sal_Bool)0); |
1012 | |
1013 | if (pKey->pfnCallback) |
1014 | pOldData = pthread_getspecific(pKey->m_key); |
1015 | |
1016 | bRet = (pthread_setspecific(pKey->m_key, pData) == 0); |
1017 | |
1018 | if (bRet && pKey->pfnCallback && pOldData) |
1019 | pKey->pfnCallback(pOldData); |
1020 | |
1021 | return bRet; |
1022 | } |
1023 | |
1024 | /*****************************************************************************/ |
1025 | /* Thread Local Text Encoding */ |
1026 | /*****************************************************************************/ |
1027 | static void osl_thread_textencoding_init_Impl (void) |
1028 | { |
1029 | rtl_TextEncoding defaultEncoding; |
1030 | const char * pszEncoding; |
1031 | |
1032 | /* create thread specific data key */ |
1033 | pthread_key_create (&(g_thread.m_textencoding.m_key), NULL((void*)0)); |
1034 | |
1035 | /* determine default text encoding */ |
1036 | pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING"); |
1037 | if (pszEncoding) |
1038 | defaultEncoding = atoi(pszEncoding); |
1039 | else |
1040 | defaultEncoding = osl_getTextEncodingFromLocale(NULL((void*)0)); |
1041 | |
1042 | OSL_ASSERT(defaultEncoding != RTL_TEXTENCODING_DONTKNOW)do { if (((sal_Bool)1) && (!(defaultEncoding != (((rtl_TextEncoding ) 0))))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ( "legacy.osl"), ("/usr/local/src/libreoffice/sal/osl/unx/thread.c" ":" "1042" ": "), "OSL_ASSERT: %s", "defaultEncoding != RTL_TEXTENCODING_DONTKNOW" ); } } while (((sal_Bool)0)); |
1043 | |
1044 | /* |
1045 | Tools string functions call abort() on an unknown encoding so ASCII |
1046 | is a meaningfull fallback regardless wether the assertion makes sense. |
1047 | */ |
1048 | |
1049 | if ( RTL_TEXTENCODING_DONTKNOW(((rtl_TextEncoding) 0)) == defaultEncoding ) |
1050 | defaultEncoding = RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)); |
1051 | |
1052 | g_thread.m_textencoding.m_default = defaultEncoding; |
1053 | } |
1054 | |
1055 | /*****************************************************************************/ |
1056 | /* osl_getThreadTextEncoding */ |
1057 | /*****************************************************************************/ |
1058 | rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding() |
1059 | { |
1060 | rtl_TextEncoding threadEncoding; |
1061 | |
1062 | pthread_once (&(g_thread.m_once), osl_thread_init_Impl); |
1063 | |
1064 | /* check for thread specific encoding, use default if not set */ |
1065 | threadEncoding = SAL_INT_CAST(((rtl_TextEncoding) ((sal_uIntPtr) pthread_getspecific(g_thread .m_textencoding.m_key))) |
1066 | rtl_TextEncoding,((rtl_TextEncoding) ((sal_uIntPtr) pthread_getspecific(g_thread .m_textencoding.m_key))) |
1067 | (sal_uIntPtr) pthread_getspecific(g_thread.m_textencoding.m_key))((rtl_TextEncoding) ((sal_uIntPtr) pthread_getspecific(g_thread .m_textencoding.m_key))); |
1068 | if (0 == threadEncoding) |
1069 | threadEncoding = g_thread.m_textencoding.m_default; |
1070 | |
1071 | return threadEncoding; |
1072 | } |
1073 | |
1074 | /*****************************************************************************/ |
1075 | /* osl_setThreadTextEncoding */ |
1076 | /*****************************************************************************/ |
1077 | rtl_TextEncoding osl_setThreadTextEncoding(rtl_TextEncoding Encoding) |
1078 | { |
1079 | rtl_TextEncoding oldThreadEncoding = osl_getThreadTextEncoding(); |
1080 | |
1081 | /* save encoding in thread local storage */ |
1082 | pthread_setspecific ( |
1083 | g_thread.m_textencoding.m_key, |
1084 | (void*) SAL_INT_CAST(sal_uIntPtr, Encoding)((sal_uIntPtr) (Encoding))); |
1085 | |
1086 | return oldThreadEncoding; |
1087 | } |
1088 | |
1089 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |