diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-02-16 16:28:44 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-02-16 16:28:57 +0100 |
| commit | 9fdd675eab7cae04dc176ea2aba2d53c59101beb (patch) | |
| tree | cb291e89411d0b73a74a3259fd651caccd0c405f /src/drivers/Posix/Fl_Posix_System_Driver.cxx | |
| parent | b709b2a2d3451ec48d454a895a459dadf7c184e5 (diff) | |
Remove FL_CFG_SYS_POSIX and FL_CFG_SYS_WIN32 preprocessor vars from Fl_lock.cxx
Diffstat (limited to 'src/drivers/Posix/Fl_Posix_System_Driver.cxx')
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index 75df02e7a..633794a86 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -171,3 +171,153 @@ int Fl_Posix_System_Driver::run_program(const char *program, char **argv, char * // Return indicating success... return 1; } + +//////////////////////////////////////////////////////////////// +// POSIX threading... +#if defined(HAVE_PTHREAD) +# include <unistd.h> +# include <fcntl.h> +# include <pthread.h> + +// Pipe for thread messaging via Fl::awake()... +static int thread_filedes[2]; + +// Mutex and state information for Fl::lock() and Fl::unlock()... +static pthread_mutex_t fltk_mutex; +static pthread_t owner; +static int counter; + +static void lock_function_init_std() { + pthread_mutex_init(&fltk_mutex, NULL); +} + +static void lock_function_std() { + if (!counter || owner != pthread_self()) { + pthread_mutex_lock(&fltk_mutex); + owner = pthread_self(); + } + counter++; +} + +static void unlock_function_std() { + if (!--counter) pthread_mutex_unlock(&fltk_mutex); +} + +# ifdef PTHREAD_MUTEX_RECURSIVE +static bool lock_function_init_rec() { + pthread_mutexattr_t attrib; + pthread_mutexattr_init(&attrib); + if (pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE)) { + pthread_mutexattr_destroy(&attrib); + return true; + } + + pthread_mutex_init(&fltk_mutex, &attrib); + return false; +} + +static void lock_function_rec() { + pthread_mutex_lock(&fltk_mutex); +} + +static void unlock_function_rec() { + pthread_mutex_unlock(&fltk_mutex); +} +# endif // PTHREAD_MUTEX_RECURSIVE + +void Fl_Posix_System_Driver::awake(void* msg) { + if (thread_filedes[1]) { + if (write(thread_filedes[1], &msg, sizeof(void*))==0) { /* ignore */ } + } +} + +static void* thread_message_; +void* Fl_Posix_System_Driver::thread_message() { + void* r = thread_message_; + thread_message_ = 0; + return r; +} + +static void thread_awake_cb(int fd, void*) { + if (read(fd, &thread_message_, sizeof(void*))==0) { + /* This should never happen */ + } + Fl_Awake_Handler func; + void *data; + while (Fl::get_awake_handler_(func, data)==0) { + (*func)(data); + } +} + +// These pointers are in Fl_x.cxx: +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +int Fl_Posix_System_Driver::lock() { + if (!thread_filedes[1]) { + // Initialize thread communication pipe to let threads awake FLTK + // from Fl::wait() + if (pipe(thread_filedes)==-1) { + /* this should not happen */ + } + + // Make the write side of the pipe non-blocking to avoid deadlock + // conditions (STR #1537) + fcntl(thread_filedes[1], F_SETFL, + fcntl(thread_filedes[1], F_GETFL) | O_NONBLOCK); + + // Monitor the read side of the pipe so that messages sent via + // Fl::awake() from a thread will "wake up" the main thread in + // Fl::wait(). + Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb); + + // Set lock/unlock functions for this system, using a system-supplied + // recursive mutex if supported... +# ifdef PTHREAD_MUTEX_RECURSIVE + if (!lock_function_init_rec()) { + fl_lock_function = lock_function_rec; + fl_unlock_function = unlock_function_rec; + } else { +# endif // PTHREAD_MUTEX_RECURSIVE + lock_function_init_std(); + fl_lock_function = lock_function_std; + fl_unlock_function = unlock_function_std; +# ifdef PTHREAD_MUTEX_RECURSIVE + } +# endif // PTHREAD_MUTEX_RECURSIVE + } + + fl_lock_function(); + return 0; +} + +void Fl_Posix_System_Driver::unlock() { + fl_unlock_function(); +} + +// Mutex code for the awake ring buffer +static pthread_mutex_t *ring_mutex; + +void Fl_Posix_System_Driver::unlock_ring() { + pthread_mutex_unlock(ring_mutex); +} + +void Fl_Posix_System_Driver::lock_ring() { + if (!ring_mutex) { + ring_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(ring_mutex, NULL); + } + pthread_mutex_lock(ring_mutex); +} + +#else // ! HAVE_PTHREAD + +void Fl_Posix_System_Driver::awake(void*) {} +int Fl_Posix_System_Driver::lock() { return 1; } +void Fl_Posix_System_Driver::unlock() {} +void* Fl_Posix_System_Driver::thread_message() { return NULL; } + +//void lock_ring() {} +//void unlock_ring() {} + +#endif // HAVE_PTHREAD |
