Author: spitzak
Date: 2007-06-19 13:50:14 -0400 (Tue, 19 Jun 2007)
New Revision: 5916
Log:
Made fltk::in_main_thread() much more reliable and made it work without
having to grab the fltk::lock().
Made fltk::awake() work without having to grab the fltk::lock().
Modified:
trunk/fltk/run.h
trunk/src/MenuBar.cxx
trunk/src/ScrollGroup.cxx
trunk/src/lock.cxx
trunk/src/osx/run.cxx
trunk/src/run.cxx
trunk/src/win32/lock.cxx
trunk/src/win32/run.cxx
trunk/src/x11/run.cxx
Modified: trunk/fltk/run.h
===================================================================
--- trunk/fltk/run.h 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/fltk/run.h 2007-06-19 17:50:14 UTC (rev 5916)
@@ -79,13 +79,11 @@
FL_API void add_fd(int fd, FileHandler, void* = 0);
FL_API void remove_fd(int, int when = -1);
-extern FL_API bool in_main_thread_;
-
FL_API void lock();
FL_API void unlock();
FL_API void awake(void* message = 0);
FL_API void* thread_message();
-inline bool in_main_thread() {return in_main_thread_;}
+FL_API bool in_main_thread();
}
Modified: trunk/src/MenuBar.cxx
===================================================================
--- trunk/src/MenuBar.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/MenuBar.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -44,7 +44,6 @@
#include <config.h>
#include <fltk/Item.h> // for TOGGLE, RADIO
#define checkmark(item) (item->type()>=Item::TOGGLE &&
item->type()<=Item::RADIO)
-#include <stdio.h>
using namespace fltk;
@@ -104,7 +103,7 @@
for (i = 0; i < children; i++) {
Widget* w = child(i);
if (w->active() && w->test_label_shortcut()) {
- if (w->is_group()) {value(i); printf("Picking %s\n", w->label());
goto J1;} // menu title
+ if (w->is_group()) {value(i); goto J1;} // menu title
focus_index(Group::find(w)); // Set focus_index, so Menu::get_item()
works
if (checkmark(w)) { w->invert_flag(STATE); redraw(); }
execute(w); // button in the menu bar
Modified: trunk/src/ScrollGroup.cxx
===================================================================
--- trunk/src/ScrollGroup.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/ScrollGroup.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -184,7 +184,7 @@
int layout_damage = this->layout_damage();
// handle movement in xy without wasting time:
- if (!(layout_damage&(LAYOUT_WH|LAYOUT_DAMAGE))) {
+ if (!(layout_damage&(LAYOUT_WH|LAYOUT_DAMAGE|LAYOUT_CHILD))) {
Group::layout();
return;
}
Modified: trunk/src/lock.cxx
===================================================================
--- trunk/src/lock.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/lock.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -154,7 +154,7 @@
# ifndef __USE_GNU
# define __USE_GNU // makes the RECURSIVE stuff appear on Linux
# endif
-#include <fltk/Threads.h>
+# include <fltk/Threads.h>
# if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && !defined(__CYGWIN__)
static pthread_mutexattr_t recursive_attrib={PTHREAD_MUTEX_RECURSIVE_NP};
@@ -162,7 +162,7 @@
# elif defined(PTHREAD_MUTEX_RECURSIVE)
static pthread_mutexattr_t* recursive_attrib() {
static pthread_mutexattr_t a;
- static bool beenhere;
+ static bool beenhere = false;
if (!beenhere) {
pthread_mutexattr_init(&a);
pthread_mutexattr_settype(&a,PTHREAD_MUTEX_RECURSIVE);
@@ -197,20 +197,27 @@
static fltk::RecursiveMutex fltkmutex;
-static void lock_function() {fltkmutex.lock();}
-static void unlock_function() {fltkmutex.unlock();}
+static void lock_function() { fltkmutex.lock(); }
+static void unlock_function() { fltkmutex.unlock(); }
+static pthread_t main_thread_id;
+
+#if !USE_QUARTZ
static void* thread_message_;
static void thread_awake_cb(int fd, void*) {
while (read(fd, &thread_message_, sizeof(void*)) > 0);
}
static int thread_filedes[2];
+#endif
static void init_function() {
// Init threads communication pipe to let threads awake FLTK from wait
+ main_thread_id = pthread_self();
pipe(thread_filedes);
+#if !USE_QUARTZ
fcntl(thread_filedes[0], F_SETFL, O_NONBLOCK);
fltk::add_fd(thread_filedes[0], fltk::READ, thread_awake_cb);
+#endif
fl_lock_function = init_or_lock_function = lock_function;
fl_unlock_function = unlock_function;
lock_function();
@@ -220,18 +227,24 @@
void fltk::unlock() {fl_unlock_function();}
+bool fltk::in_main_thread() {
+ return init_or_lock_function == init_function || pthread_self() ==
main_thread_id;
+}
+
+#if !USE_QUARTZ
void fltk::awake(void* msg) {
write(thread_filedes[1], &msg, sizeof(void*));
}
// the following is already defined in CYGWIN
// for the common win32/run.cxx part
-#if !defined(__CYGWIN__)
+# if !defined(__CYGWIN__)
void* fltk::thread_message() {
void* r = thread_message_;
thread_message_ = 0;
return r;
}
+# endif
#endif
#else
Modified: trunk/src/osx/run.cxx
===================================================================
--- trunk/src/osx/run.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/osx/run.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -215,22 +215,33 @@
DEBUGMSG("reading from G_pipe\n");
char buf[1]; read(G_pipe[0],buf,1);
}
- // wake up the main thread with a message:
- EventRef drEvent;
- CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
- 0, kEventAttributeUserEvent, &drEvent);
- PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard);
+ fltk::awake();
}
}
}
+static void* thread_message_;
+void fltk::awake(void* msg) {
+ thread_message_ = msg;
+ // wake up the main thread with a message:
+ EventRef drEvent;
+ CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
+ 0, kEventAttributeUserEvent, &drEvent);
+ PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard);
+}
+
+void* fltk::thread_message() {
+ void* r = thread_message_;
+ thread_message_ = 0;
+ return r;
+}
+
// Main thread calls this when it gets the above data-ready message:
// This does nothing right now because above code did the callbacks:
static void HandleDataReady()
{
#if 0
fl_lock_function();
- in_main_thread_ = true;
timeval t = { 0, 0 }; // quick check
fd_set r = fdsets[0];
fd_set w = fdsets[1];
@@ -251,7 +262,6 @@
}
}
}
- in_main_thread_ = false;
fl_unlock_function();
#endif
}
@@ -364,9 +374,7 @@
case kEventCommandProcess:
GetEventParameter( event, kEventParamDirectObject, typeHICommand,
NULL, sizeof(HICommand), NULL, &cmd );
fl_lock_function();
- in_main_thread_ = true;
ret = HandleMenu( &cmd );
- in_main_thread_ = false;
fl_unlock_function();
break;
}
@@ -442,7 +450,6 @@
(void*)GetCurrentEventQueue());
}
- in_main_thread_ = false;
fl_unlock_function();
EventRef event;
@@ -474,7 +481,6 @@
time = 0.0; // just peek for pending events
}
fl_lock_function();
- in_main_thread_ = true;
// we send LEAVE only if the mouse did not enter some other window:
// I'm not sure if this is needed or if it works...
@@ -555,7 +561,6 @@
OSStatus ret = noErr;
Window *window = (Window*)userData;
fl_lock_function();
- in_main_thread_ = true;
switch ( kind )
{
@@ -615,7 +620,6 @@
ret = eventNotHandledErr;
break;
}
- in_main_thread_ = false;
fl_unlock_function();
return ret;
}
@@ -637,7 +641,6 @@
NULL, sizeof(long), NULL, &delta );
OSStatus ret = noErr;
fl_lock_function();
- in_main_thread_ = true;
if ( axis == kEventMouseWheelAxisX ) {
e_dx = -delta;
e_dy = 0;
@@ -649,7 +652,6 @@
} else {
ret = eventNotHandledErr;
}
- in_main_thread_ = false;
fl_unlock_function();
return ret;
}
@@ -691,7 +693,6 @@
static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler,
EventRef event, void *userData )
{
fl_lock_function();
- in_main_thread_ = true;
os_event = event;
Window *window = (Window*)userData;
@@ -713,18 +714,15 @@
fix_xfocus(window);
if ( FindWindow( pos, 0 ) != inContent ) {
// let the OS handle clicks in the title bar
- in_main_thread_ = false;
fl_unlock_function();
return CallNextEventHandler( nextHandler, event );
}
if ( !IsWindowActive( fltk::xid(window) ) ) {
// let the OS handle the activation,
// but continue to get a click-through effect
- in_main_thread_ = false;
fl_unlock_function();
CallNextEventHandler( nextHandler, event );
fl_lock_function();
- in_main_thread_ = true;
}
os_capture = fltk::xid(window); // make all mouse events go to this window
px = pos.h; py = pos.v;
@@ -756,7 +754,6 @@
break;
}
- in_main_thread_ = false;
fl_unlock_function();
return noErr;
}
@@ -845,7 +842,6 @@
unsigned short sym;
fl_lock_function();
- in_main_thread_ = true;
if (!xfocus) fix_xfocus((Window*)userData);
switch ( GetEventKind( event ) )
@@ -912,7 +908,6 @@
break; }
}
bool r = (sendEvent && handle(sendEvent, xfocus));
- in_main_thread_ = false;
fl_unlock_function();
if (r) return noErr;
return CallNextEventHandler( nextHandler, event );
Modified: trunk/src/run.cxx
===================================================================
--- trunk/src/run.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/run.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -127,8 +127,6 @@
}
} /* extern "C" */
-bool fltk::in_main_thread_ = true;
-
/*! Tries to make this widget be the keyboard focus widget, by first
sending it an fltk::FOCUS event, and if it returns non-zero, setting
fltk::focus() to this widget. You should use this method to assign
Modified: trunk/src/win32/lock.cxx
===================================================================
--- trunk/src/win32/lock.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/win32/lock.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -17,21 +17,25 @@
EnterCriticalSection(&cs);
}
-static DWORD main_thread;
+static DWORD main_thread_id;
static void init_function() {
InitializeCriticalSection(&cs);
lock_function();
fl_lock_function = init_or_lock_function = lock_function;
fl_unlock_function = unlock_function;
- main_thread = GetCurrentThreadId();
+ main_thread_id = GetCurrentThreadId();
}
void fltk::lock() {init_or_lock_function();}
void fltk::unlock() {fl_unlock_function();}
+bool fltk::in_main_thread() {
+ return init_or_lock_function == init_function || GetCurrentThreadId() ==
main_thread_id;
+}
+
#define WM_MAKEWAITRETURN (WM_USER+0x401)
void fltk::awake(void* msg) {
- PostThreadMessage( main_thread, WM_MAKEWAITRETURN, (WPARAM)msg, 0);
+ PostThreadMessage( main_thread_id, WM_MAKEWAITRETURN, (WPARAM)msg, 0);
}
Modified: trunk/src/win32/run.cxx
===================================================================
--- trunk/src/win32/run.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/win32/run.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -424,14 +424,12 @@
#endif // USE_ASYNC_SELECT
if (!fl_ready()) {
- in_main_thread_ = false;
fl_unlock_function();
int t_msec =
time_to_wait < 2147483.647 ? int(time_to_wait*1000+.5) : 0x7fffffff;
// int ret_val =
MsgWaitForMultipleObjects(0, NULL, false, t_msec, QS_ALLINPUT);
fl_lock_function();
- in_main_thread_ = true;
}
// Execute all pending messages:
Modified: trunk/src/x11/run.cxx
===================================================================
--- trunk/src/x11/run.cxx 2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/x11/run.cxx 2007-06-19 17:50:14 UTC (rev 5916)
@@ -426,7 +426,6 @@
fdt[2] = fdsets[2];
#endif
- in_main_thread_ = false;
fl_unlock_function();
#if USE_POLL
int n = ::poll(pollfds, nfds,
@@ -443,7 +442,6 @@
}
#endif
fl_lock_function();
- in_main_thread_ = true;
if (n > 0) {
for (int i=0; i<nfds; i++) {
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit