/* * BRLTTY - A background process providing access to the console screen (when in * text mode) for a blind person using a refreshable braille display. * * Copyright (C) 1995-2021 by The BRLTTY Developers. * * BRLTTY comes with ABSOLUTELY NO WARRANTY. * * This is free software, placed under the terms of the * GNU Lesser General Public License, as published by the Free Software * Foundation; either version 2.1 of the License, or (at your option) any * later version. Please see the file LICENSE-LGPL for details. * * Web Page: http://brltty.app/ * * This software is maintained by Dave Mielke . */ #ifndef BRLTTY_INCLUDED_THREAD #define BRLTTY_INCLUDED_THREAD #include "get_thread.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifdef GOT_PTHREADS #define THREAD_FUNCTION(name) void *name (void *argument) typedef THREAD_FUNCTION(ThreadFunction); extern int createThread ( const char *name, pthread_t *thread, const pthread_attr_t *attributes, ThreadFunction *function, void *argument ); extern int callThreadFunction ( const char *name, ThreadFunction *function, void *argument, void **result ); extern int lockMutex (pthread_mutex_t *mutex); extern int unlockMutex (pthread_mutex_t *mutex); #endif /* GOT_PTHREADS */ extern size_t formatThreadName (char *buffer, size_t size); extern void setThreadName (const char *name); #if defined(PTHREAD_MUTEX_INITIALIZER) typedef pthread_mutex_t CriticalSectionLock; #define CRITICAL_SECTION_LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER static inline void enterCriticalSection (CriticalSectionLock *lock) { pthread_mutex_lock(lock); } static inline void leaveCriticalSection (CriticalSectionLock *lock) { pthread_mutex_unlock(lock); } #else /* critical section lock */ typedef unsigned char CriticalSectionLock; #define CRITICAL_SECTION_LOCK_INITIALIZER 0 static inline void enterCriticalSection (CriticalSectionLock *lock) { } static inline void leaveCriticalSection (CriticalSectionLock *lock) { } #endif /* critical section lock */ #define THREAD_SPECIFIC_DATA_NEW(name) void *name##_new (void) typedef THREAD_SPECIFIC_DATA_NEW(ThreadSpecificData); #define THREAD_SPECIFIC_DATA_DESTROY(name) void name##_destroy (void *data) typedef THREAD_SPECIFIC_DATA_DESTROY(ThreadSpecificData); typedef struct { ThreadSpecificData_new *new; ThreadSpecificData_destroy *destroy; #if defined(PTHREAD_MUTEX_INITIALIZER) pthread_mutex_t mutex; struct { pthread_key_t value; unsigned created; } key; #define THREAD_SPECIFIC_DATA_INITIALIZER() \ .mutex = PTHREAD_MUTEX_INITIALIZER, .key = { .created = 0 } #else /* thread specific data */ void *data; #define THREAD_SPECIFIC_DATA_INITIALIZER() \ .data = NULL #endif /* thread specific data */ } ThreadSpecificDataControl; #define THREAD_SPECIFIC_DATA_CONTROL(name) \ static ThreadSpecificDataControl name = { \ .new = name ## _new, \ .destroy = name ## _destroy, \ \ THREAD_SPECIFIC_DATA_INITIALIZER() \ } extern void *getThreadSpecificData (ThreadSpecificDataControl *ctl); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* BRLTTY_INCLUDED_THREAD */