|
|
|
@ -1,80 +1,132 @@
@@ -1,80 +1,132 @@
|
|
|
|
|
/* Fl_Lock.cxx
|
|
|
|
|
//
|
|
|
|
|
// "$Id: Fl_lock.cxx,v 1.13.2.1 2001/12/06 22:16:49 easysw Exp $"
|
|
|
|
|
//
|
|
|
|
|
// Multi-threading support code for the Fast Light Tool Kit (FLTK).
|
|
|
|
|
//
|
|
|
|
|
// Copyright 1998-2001 by Bill Spitzak and others.
|
|
|
|
|
//
|
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
|
// modify it under the terms of the GNU Library General Public
|
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
// Library General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU Library General Public
|
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
|
// USA.
|
|
|
|
|
//
|
|
|
|
|
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <FL/Fl.H> |
|
|
|
|
#include <config.h> |
|
|
|
|
|
|
|
|
|
I would prefer that fltk contain the minimal amount of extra stuff |
|
|
|
|
for doing threads. There are other portable thread wrapper libraries |
|
|
|
|
out there and fltk should not be providing another. This file |
|
|
|
|
is an attempt to make minimal additions and make them self-contained |
|
|
|
|
in this source file. |
|
|
|
|
/*
|
|
|
|
|
From Bill: |
|
|
|
|
|
|
|
|
|
Fl::lock() - recursive lock. Plus you must call this before the |
|
|
|
|
first call to Fl::wait()/run() to initialize the thread system. |
|
|
|
|
The lock is locked all the time except when Fl::wait() is waiting |
|
|
|
|
for events. |
|
|
|
|
I would prefer that FLTK contain the minimal amount of extra |
|
|
|
|
stuff for doing threads. There are other portable thread |
|
|
|
|
wrapper libraries out there and FLTK should not be providing |
|
|
|
|
another. This file is an attempt to make minimal additions |
|
|
|
|
and make them self-contained in this source file. |
|
|
|
|
|
|
|
|
|
Fl::unlock() - release the recursive lock. |
|
|
|
|
Fl::lock() - recursive lock. You must call this before the |
|
|
|
|
first call to Fl::wait()/run() to initialize the thread |
|
|
|
|
system. The lock is locked all the time except when |
|
|
|
|
Fl::wait() is waiting for events. |
|
|
|
|
|
|
|
|
|
Fl::awake(void*) - Causes Fl::wait() to return (with the lock locked) |
|
|
|
|
even if there are no events ready. |
|
|
|
|
Fl::unlock() - release the recursive lock. |
|
|
|
|
|
|
|
|
|
Fl::thread_message() - returns an argument sent to an Fl::awake call, |
|
|
|
|
or returns null if none. Warning: the current implementation only |
|
|
|
|
has a one-entry queue and only returns the most recent value! |
|
|
|
|
Fl::awake(void*) - Causes Fl::wait() to return (with the lock |
|
|
|
|
locked) even if there are no events ready. |
|
|
|
|
|
|
|
|
|
See also the Fl_Threads.h header file, which provides convienence |
|
|
|
|
functions so you can create your own threads and mutexes. |
|
|
|
|
Fl::thread_message() - returns an argument sent to an |
|
|
|
|
Fl::awake() call, or returns NULL if none. WARNING: the |
|
|
|
|
current implementation only has a one-entry queue and only |
|
|
|
|
returns the most recent value! |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <fltk/Fl.h> |
|
|
|
|
#include <config.h> |
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
|
// Windows threading...
|
|
|
|
|
#ifdef WIN32 |
|
|
|
|
# include <windows.h> |
|
|
|
|
# include <process.h> |
|
|
|
|
|
|
|
|
|
#include <windows.h> |
|
|
|
|
#include <process.h> |
|
|
|
|
|
|
|
|
|
// these pointers are in Fl_win32.cxx:
|
|
|
|
|
// These pointers are in Fl_win32.cxx:
|
|
|
|
|
extern void (*fl_lock_function)(); |
|
|
|
|
extern void (*fl_unlock_function)(); |
|
|
|
|
|
|
|
|
|
// The main thread's ID
|
|
|
|
|
static DWORD main_thread; |
|
|
|
|
|
|
|
|
|
// Microsoft's version of a MUTEX...
|
|
|
|
|
CRITICAL_SECTION cs; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'unlock_function()' - Release the lock.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static void unlock_function() { |
|
|
|
|
LeaveCriticalSection(&cs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'lock_function()' - Get the lock.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static void lock_function() { |
|
|
|
|
EnterCriticalSection(&cs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'Fl::lock()' - Lock access to FLTK data structures...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void Fl::lock() { |
|
|
|
|
if (!main_thread) |
|
|
|
|
InitializeCriticalSection(&cs); |
|
|
|
|
if (!main_thread) InitializeCriticalSection(&cs); |
|
|
|
|
|
|
|
|
|
lock_function(); |
|
|
|
|
|
|
|
|
|
if (!main_thread) { |
|
|
|
|
fl_lock_function = lock_function; |
|
|
|
|
fl_lock_function = lock_function; |
|
|
|
|
fl_unlock_function = unlock_function; |
|
|
|
|
main_thread = GetCurrentThreadId(); |
|
|
|
|
main_thread = GetCurrentThreadId(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'Fl::unlock()' - Unlock access to FLTK data structures...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void Fl::unlock() { |
|
|
|
|
unlock_function(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// when called from a thread, it causes FLTK to awake from Fl::wait()
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'Fl::awake()' - Let the main thread know an update is pending.
|
|
|
|
|
//
|
|
|
|
|
// When called from a thread, it causes FLTK to awake from Fl::wait()...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void Fl::awake(void* msg) { |
|
|
|
|
PostThreadMessage( main_thread, WM_USER, (WPARAM)msg, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
// POSIX threading...
|
|
|
|
|
#elif HAVE_PTHREAD |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <pthread.h> |
|
|
|
|
# include <unistd.h> |
|
|
|
|
# include <pthread.h> |
|
|
|
|
|
|
|
|
|
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP |
|
|
|
|
# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP |
|
|
|
|
// Linux supports recursive locks, use them directly:
|
|
|
|
|
|
|
|
|
|
static pthread_mutex_t fltk_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; |
|
|
|
@ -90,7 +142,7 @@ void Fl::unlock() {
@@ -90,7 +142,7 @@ void Fl::unlock() {
|
|
|
|
|
// this is needed for the Fl_Mutex constructor:
|
|
|
|
|
pthread_mutexattr_t Fl_Mutex_attrib = {PTHREAD_MUTEX_RECURSIVE_NP}; |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
# else |
|
|
|
|
// Make a recursive lock out of the pthread mutex:
|
|
|
|
|
|
|
|
|
|
static pthread_mutex_t fltk_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
|
|
@ -99,7 +151,8 @@ static int counter;
@@ -99,7 +151,8 @@ static int counter;
|
|
|
|
|
|
|
|
|
|
static void lock_function() { |
|
|
|
|
if (!counter || owner != pthread_self()) { |
|
|
|
|
pthread_mutex_lock(&fltk_mutex); owner = pthread_self(); |
|
|
|
|
pthread_mutex_lock(&fltk_mutex); |
|
|
|
|
owner = pthread_self(); |
|
|
|
|
} |
|
|
|
|
counter++; |
|
|
|
|
} |
|
|
|
@ -108,11 +161,12 @@ void Fl::unlock() {
@@ -108,11 +161,12 @@ void Fl::unlock() {
|
|
|
|
|
if (!--counter) pthread_mutex_unlock(&fltk_mutex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
// Pipe for thread messaging...
|
|
|
|
|
static int thread_filedes[2]; |
|
|
|
|
|
|
|
|
|
// these pointers are in Fl_x.cxx:
|
|
|
|
|
// These pointers are in Fl_x.cxx:
|
|
|
|
|
extern void (*fl_lock_function)(); |
|
|
|
|
extern void (*fl_unlock_function)(); |
|
|
|
|
|
|
|
|
@ -133,7 +187,7 @@ void Fl::lock() {
@@ -133,7 +187,7 @@ void Fl::lock() {
|
|
|
|
|
// Init threads communication pipe to let threads awake FLTK from wait
|
|
|
|
|
pipe(thread_filedes); |
|
|
|
|
Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb); |
|
|
|
|
fl_lock_function = lock_function; |
|
|
|
|
fl_lock_function = lock_function; |
|
|
|
|
fl_unlock_function = Fl::unlock; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -143,3 +197,7 @@ void Fl::awake(void* msg) {
@@ -143,3 +197,7 @@ void Fl::awake(void* msg) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// End of "$Id: Fl_lock.cxx,v 1.13.2.1 2001/12/06 22:16:49 easysw Exp $".
|
|
|
|
|
//
|
|
|
|
|