summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_lock.cxx134
-rw-r--r--src/Fl_win32.cxx29
-rw-r--r--src/Fl_x.cxx14
-rw-r--r--src/Makefile5
-rw-r--r--src/makedepend31
5 files changed, 160 insertions, 53 deletions
diff --git a/src/Fl_lock.cxx b/src/Fl_lock.cxx
index ebd8b420f..8f9d16378 100644
--- a/src/Fl_lock.cxx
+++ b/src/Fl_lock.cxx
@@ -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() {
// 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;
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() {
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() {
// 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) {
}
#endif
+
+//
+// End of "$Id: Fl_lock.cxx,v 1.13.2.1 2001/12/06 22:16:49 easysw Exp $".
+//
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index de80c9d0a..c54687a60 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_win32.cxx,v 1.33.2.37.2.9 2001/11/30 16:10:08 easysw Exp $"
+// "$Id: Fl_win32.cxx,v 1.33.2.37.2.10 2001/12/06 22:16:49 easysw Exp $"
//
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
//
@@ -164,6 +164,18 @@ void Fl::remove_fd(int n) {
remove_fd(n, -1);
}
+// these pointers are set by the Fl::lock() function:
+static void nothing() {}
+void (*fl_lock_function)() = nothing;
+void (*fl_unlock_function)() = nothing;
+
+static void* thread_message_;
+void* Fl::thread_message() {
+ void* r = thread_message_;
+ thread_message_ = 0;
+ return r;
+}
+
MSG fl_msg;
// This is never called with time_to_wait < 0.0.
@@ -206,12 +218,17 @@ int fl_wait(double time_to_wait) {
}
#endif // USE_ASYNC_SELECT
+ fl_unlock_function();
+
if (time_to_wait < 2147483.648) {
// Perform the requested timeout...
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
if (!have_message) {
int t = (int)(time_to_wait * 1000.0 + .5);
- if (t <= 0) return 0; // too short to measure
+ if (t <= 0) { // too short to measure
+ fl_lock_function();
+ return 0;
+ }
timerid = SetTimer(NULL, 0, t, NULL);
have_message = GetMessage(&fl_msg, NULL, 0, 0);
KillTimer(NULL, timerid);
@@ -220,6 +237,8 @@ int fl_wait(double time_to_wait) {
have_message = GetMessage(&fl_msg, NULL, 0, 0);
}
+ fl_lock_function();
+
// Execute the message we got, and all other pending messages:
while (have_message) {
#ifdef USE_ASYNC_SELECT
@@ -233,6 +252,10 @@ int fl_wait(double time_to_wait) {
// looks like it is best to do the dispatch-message anyway:
}
#endif
+
+ if (fl_msg.message == WM_USER) // Used for awaking wait() from another thread
+ thread_message_ = (void*)fl_msg.wParam;
+
TranslateMessage(&fl_msg);
DispatchMessage(&fl_msg);
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
@@ -997,5 +1020,5 @@ void Fl_Window::make_current() {
}
//
-// End of "$Id: Fl_win32.cxx,v 1.33.2.37.2.9 2001/11/30 16:10:08 easysw Exp $".
+// End of "$Id: Fl_win32.cxx,v 1.33.2.37.2.10 2001/12/06 22:16:49 easysw Exp $".
//
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 5788181d6..7572d7d02 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_x.cxx,v 1.24.2.24.2.7 2001/11/27 17:44:06 easysw Exp $"
+// "$Id: Fl_x.cxx,v 1.24.2.24.2.8 2001/12/06 22:16:49 easysw Exp $"
//
// X specific code for the Fast Light Tool Kit (FLTK).
//
@@ -179,6 +179,11 @@ static void do_queued_events() {
# endif
}
+// these pointers are set by the Fl::lock() function:
+static void nothing() {}
+void (*fl_lock_function)() = nothing;
+void (*fl_unlock_function)() = nothing;
+
// This is never called with time_to_wait < 0.0:
// It should return negative on error, 0 if nothing happens before
// timeout, and >0 if any callbacks were done.
@@ -197,6 +202,8 @@ int fl_wait(double time_to_wait) {
# endif
int n;
+ fl_unlock_function();
+
if (time_to_wait < 2147483.648) {
# if USE_POLL
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
@@ -213,6 +220,9 @@ int fl_wait(double time_to_wait) {
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
# endif
}
+
+ fl_lock_function();
+
if (n > 0) {
for (int i=0; i<nfds; i++) {
# if USE_POLL
@@ -937,5 +947,5 @@ void Fl_Window::make_current() {
#endif
//
-// End of "$Id: Fl_x.cxx,v 1.24.2.24.2.7 2001/11/27 17:44:06 easysw Exp $".
+// End of "$Id: Fl_x.cxx,v 1.24.2.24.2.8 2001/12/06 22:16:49 easysw Exp $".
//
diff --git a/src/Makefile b/src/Makefile
index 89c5746a4..7d105f5f7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile,v 1.18.2.14.2.23 2001/12/06 18:23:29 easysw Exp $"
+# "$Id: Makefile,v 1.18.2.14.2.24 2001/12/06 22:16:49 easysw Exp $"
#
# Library makefile for the Fast Light Tool Kit (FLTK).
#
@@ -108,6 +108,7 @@ CPPFILES = \
Fl_get_key.cxx \
Fl_get_system_colors.cxx \
Fl_grab.cxx \
+ Fl_lock.cxx \
Fl_own_colormap.cxx \
Fl_visual.cxx \
Fl_x.cxx \
@@ -299,5 +300,5 @@ uninstall:
#
-# End of "$Id: Makefile,v 1.18.2.14.2.23 2001/12/06 18:23:29 easysw Exp $".
+# End of "$Id: Makefile,v 1.18.2.14.2.24 2001/12/06 22:16:49 easysw Exp $".
#
diff --git a/src/makedepend b/src/makedepend
index 068b94b35..bddc261e6 100644
--- a/src/makedepend
+++ b/src/makedepend
@@ -269,6 +269,7 @@ Fl_get_system_colors.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
Fl_get_system_colors.o: ../FL/x.H ../FL/Fl_Window.H ../FL/math.h
Fl_grab.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
Fl_grab.o: ../FL/x.H ../FL/Fl_Window.H
+Fl_lock.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H ../config.h
Fl_own_colormap.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H
Fl_own_colormap.o: ../FL/Fl_Export.H ../FL/x.H ../FL/Fl_Window.H
Fl_visual.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
@@ -280,7 +281,7 @@ filename_absolute.o: ../FL/filename.H ../FL/Fl_Export.H flstring.h
filename_absolute.o: ../config.h
filename_expand.o: ../FL/filename.H ../FL/Fl_Export.H
filename_ext.o: ../FL/filename.H ../FL/Fl_Export.H
-filename_isdir.o: ../config.h ../FL/filename.H ../FL/Fl_Export.H
+filename_isdir.o: flstring.h ../config.h ../FL/filename.H ../FL/Fl_Export.H
filename_list.o: ../config.h ../FL/filename.H ../FL/Fl_Export.H
filename_match.o: ../FL/filename.H ../FL/Fl_Export.H
filename_setext.o: ../FL/filename.H ../FL/Fl_Export.H
@@ -443,13 +444,27 @@ forms_pixmap.o: ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H ../FL/Fl_Positioner.H
forms_pixmap.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Timer.H
forms_timer.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
forms_timer.o: ../FL/Fl_Timer.H ../FL/Fl_Widget.H ../FL/fl_draw.H
-Fl_Gl_Choice.o: ../config.h
-Fl_Gl_Overlay.o: ../config.h
-Fl_Gl_Window.o: ../config.h
-gl_draw.o: ../config.h
-gl_start.o: ../config.h
-glut_compatability.o: ../config.h
-glut_font.o: ../config.h
+Fl_Gl_Choice.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Gl_Choice.o: ../FL/x.H ../FL/Fl_Window.H Fl_Gl_Choice.H
+Fl_Gl_Overlay.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H
+Fl_Gl_Overlay.o: ../FL/Fl_Export.H ../FL/x.H ../FL/Fl_Window.H Fl_Gl_Choice.H
+Fl_Gl_Overlay.o: ../FL/Fl_Gl_Window.H
+Fl_Gl_Window.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Gl_Window.o: ../FL/x.H ../FL/Fl_Window.H Fl_Gl_Choice.H
+Fl_Gl_Window.o: ../FL/Fl_Gl_Window.H
+gl_draw.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+gl_draw.o: ../FL/gl.h ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
+gl_draw.o: Fl_Gl_Choice.H Fl_Font.H
+gl_start.o: ../config.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+gl_start.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H
+gl_start.o: ../FL/Fl_Window.H ../FL/fl_draw.H Fl_Gl_Choice.H
+glut_compatability.o: ../config.h ../FL/glut.H ../FL/gl.h
+glut_compatability.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/Fl.H
+glut_compatability.o: ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+glut_compatability.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H
+glut_font.o: ../config.h ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
+glut_font.o: ../FL/Fl_Export.H ../FL/Fl.H ../FL/Fl_Gl_Window.H
+glut_font.o: ../FL/Fl_Window.H
scandir.o: ../config.h
numericsort.o: ../config.h
vsnprintf.o: ../config.h