FLTK 2.0 threading support under FLTK 1.1. Needs porting to OSX.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1819 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Michael R Sweet 2001-12-06 22:16:49 +00:00
parent 7710dc14a8
commit ba2be02ab2
10 changed files with 216 additions and 70 deletions

28
CHANGES
View File

@ -1,9 +1,21 @@
CHANGES IN FLTK 1.1.0b7
- Some Win32 drivers would draw into wrong buffers
after OpenGL mode change
- Mac OS X support works 95%
- More documentation updates...
- Added Fl::lock() and friends from FLTK 2.0 to
support multi-threaded applications.
- Fl_Check_Button and Fl_Round_Button now use the
FL_NO_BOX box type to show the background of the
parent widget.
- Tweeked the plastic boxtype code to draw with the
right shading for narrow, but horizontal buttons.
- Fl_Progress now shades the bounding box instead of
drawing a polygon inside it.
- Fl::warning() under WIN32 defaults to no action. This
avoids warning dialogs when an image file cannot be
loaded.
- Some Win32 drivers would draw into wrong buffers
after OpenGL mode change
- Mac OS X support works 95%
- The file chooser would cause a segfault if you
clicked in an empty area of the file list.
- Fl_File_Icon::labeltype() would cause a segfault
@ -58,16 +70,6 @@ CHANGES IN FLTK 1.1.0b7
selection and text as Fl_Input_ and friends.
- Changed the default line scrolling in Fl_Text_Display
to 3 lines for the mouse wheel and scrollbar arrows.
- Fl_Check_Button and Fl_Round_Button now use the
FL_NO_BOX box type to show the background of the
parent widget.
- Tweeked the plastic boxtype code to draw with the
right shading for narrow, but horizontal buttons.
- Fl_Progress now shades the bounding box instead of
drawing a polygon inside it.
- Fl::warning() under WIN32 defaults to no action. This
avoids warning dialogs when an image file cannot be
loaded.
CHANGES IN FLTK 1.1.0b6

10
FL/Fl.H
View File

@ -1,5 +1,5 @@
//
// "$Id: Fl.H,v 1.8.2.11.2.6 2001/11/28 20:43:44 easysw Exp $"
// "$Id: Fl.H,v 1.8.2.11.2.7 2001/12/06 22:16:49 easysw Exp $"
//
// Main header file for the Fast Light Tool Kit (FLTK).
//
@ -220,10 +220,16 @@ public:
// Visible focus methods...
static void visible_focus(int v) { visible_focus_ = v; }
static int visible_focus() { return visible_focus_; }
// Multithreading support:
static void lock();
static void unlock();
static void awake(void* message = 0);
static void* thread_message();
};
#endif // !Fl_H
//
// End of "$Id: Fl.H,v 1.8.2.11.2.6 2001/11/28 20:43:44 easysw Exp $".
// End of "$Id: Fl.H,v 1.8.2.11.2.7 2001/12/06 22:16:49 easysw Exp $".
//

View File

@ -1,7 +1,7 @@
dnl -*- sh -*-
dnl the "configure" script is made from this by running GNU "autoconf"
dnl
dnl "$Id: configure.in,v 1.33.2.31.2.36 2001/12/06 02:20:36 matthiaswm Exp $"
dnl "$Id: configure.in,v 1.33.2.31.2.37 2001/12/06 22:16:48 easysw Exp $"
dnl
dnl Configuration script for the Fast Light Tool Kit (FLTK).
dnl
@ -159,6 +159,7 @@ AC_ARG_ENABLE(shared, [ --enable-shared turn on shared libraries [defau
;;
esac
fi])
AC_ARG_ENABLE(threads, [ --disable-threads disable multi-threading support],,enable_threads=yes)
AC_PROG_CC
AC_PROG_CXX
@ -299,12 +300,23 @@ case $uname in
GLDSONAME=""
GLDEMOS=""
fi
# Don't make symlinks because HFS+ is not case sensitive...
HLINKS="#"
# Add a postbuild step after linking applications
POSTBUILD="/Developer/Tools/Rez -t APPL ../FL/mac.r -o \$@"
;;
*)
dnl Check for pthreads for multi-threaded apps...
if test "$enable_threads" = yes; then
AC_SEARCH_LIBS(pthread_create, pthread)
fi
if test "x$ac_cv_search_pthread" != x; then
AC_DEFINE(HAVE_PTHREAD)
fi
dnl Check for X11...
AC_PATH_XTRA
@ -592,5 +604,5 @@ AC_OUTPUT(makeinclude fltk.list fltk-config FL/Makefile)
chmod +x fltk-config
dnl
dnl End of "$Id: configure.in,v 1.33.2.31.2.36 2001/12/06 02:20:36 matthiaswm Exp $".
dnl End of "$Id: configure.in,v 1.33.2.31.2.37 2001/12/06 22:16:48 easysw Exp $".
dnl

View File

@ -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".
//
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::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.
#include <FL/Fl.H>
#include <config.h>
/*
From Bill:
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::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::unlock() - release the recursive lock.
Fl::awake(void*) - Causes Fl::wait() to return (with the lock locked)
even if there are no events ready.
Fl::awake(void*) - Causes Fl::wait() to return (with the lock
locked) even if there are no events ready.
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!
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 $".
//

View File

@ -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 $".
//

View File

@ -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 $".
//

View File

@ -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 $".
#

View File

@ -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

View File

@ -339,6 +339,10 @@ SOURCE=..\src\fl_line_style.cxx
# End Source File
# Begin Source File
SOURCE=..\src\Fl_lock.cxx
# End Source File
# Begin Source File
SOURCE=..\src\Fl_Menu.cxx
# End Source File
# Begin Source File

View File

@ -1143,6 +1143,21 @@ DEP_CPP_FL_LIN=\
# End Source File
# Begin Source File
SOURCE=..\src\Fl_lock.cxx
DEP_CPP_FL_LOC=\
"..\fl\enumerations.h"\
"..\fl\fl_draw.h"\
"..\fl\fl_export.h"\
"..\fl\fl_group.h"\
"..\fl\fl_widget.h"\
"..\fl\fl_window.h"\
"..\fl\mac.H"\
"..\fl\win32.h"\
"..\fl\x.h"\
# End Source File
# Begin Source File
SOURCE=..\src\Fl_Menu.cxx
DEP_CPP_FL_ME=\
"..\fl\enumerations.h"\