From 18f2016b1f743068cd3d4bb9740845c2d55af3f3 Mon Sep 17 00:00:00 2001
From: Matthias Melcher
The awake() method sends a message pointer to the main thread, causing any pending Fl::wait() call to terminate so that the main thread can retrieve the message and any pending redraws can be processed. +
Multiple calls to Fl::awake() will queue multiple pointers for the main thread to process, up to a system-defined (typically several thousand) depth. The default message handler saves the last message which can be accessed using the Fl::thread_message() function. Use the Fl::set_awake_cb() function to register your own thread message handler that is called for every message received by the main thread. +
The awake() method sends a message pointer to the main thread, +causing any pending Fl::wait() call to +terminate so that the main thread can retrieve the message and any pending +redraws can be processed. + +
Multiple calls to Fl::awake() will queue multiple pointers +for the main thread to process, up to a system-defined (typically several +thousand) depth. The default message handler saves the last message which +can be accessed using the +Fl::thread_message() function. + +
The second form of awake() registers a function that will be +called by the main thread during the next message handling cycle. +awake() will return 0 if the callback function was registered, +and -1 if registration failed. Over a thousand awake callbacks can be +registered simultaneously.
See also: multithreading. @@ -1169,10 +1183,6 @@ of this.
Sets a function to handle thread messages sent via the Fl::awake() function.
-You can now start as many threads as you like. From within a thread (other than the main thread) FLTK calls must be wrapped -with calls to Fl::lock() and Fl::unlock(): +with calls to Fl::lock() +and Fl::unlock():
Fl::lock(); // avoid conflicting calls
@@ -39,27 +40,28 @@ with calls to Fl::lock() and Fl::awake(msg):
+You can send messages from child threads to the main thread
+using Fl::awake(msg):
void *msg; // "msg" is a pointer to your message
Fl::awake(msg); // send "msg" to main thread
-These messages can be read by the main thread using Fl::thread_message() or by registering a message callback with Fl::set_awake_cb():
+You can also tell the main thread to call a function for you
+as soon as possible by using
+Fl::awake(callback, userdata):
- void message_cb(void *msg) {
- ... do something with "msg" ...
+ void do_something(void *userdata) {
+ // running with the main thread
}
- int main() {
- Fl::lock();
- Fl::set_awake_cb(message_cb);
- /* run thread */
- return (Fl::run());
- }
+ // running in another thread
+ void *data; // "data" is a pointer to your user data
+ Fl::awake(do_something, data); // call something in main thread
+
FLTK supports multiple platforms, some of them which do not
allow any other but the main thread to handle system events and
@@ -86,7 +88,6 @@ related methods that will handle system messages
See also:
void awake(void *message),
void lock(),
-void set_awake_cb(void (*cb)(void *),
void *thread_message(),
void unlock().
diff --git a/src/Fl_lock.cxx b/src/Fl_lock.cxx
index 612d351b0..1f014dbfe 100644
--- a/src/Fl_lock.cxx
+++ b/src/Fl_lock.cxx
@@ -58,9 +58,8 @@
Fl::awake(void*) - Causes Fl::wait() to return (with the lock
locked) even if there are no events ready.
- Fl::set_awake_cb(void (*cb)(void *)) - Registers a function
- to call for Fl::awake() messages that is called for each
- message received.
+ Fl::awake(void (*cb)(void *), void*) - Call a function
+ in the main thread from within another thread of execution.
Fl::thread_message() - returns an argument sent to an
Fl::awake() call, or returns NULL if none. WARNING: the
@@ -68,8 +67,6 @@
returns the most recent value!
*/
-void (*Fl::awake_cb)(void *);
-
Fl_Awake_Handler *Fl::awake_ring_;
void **Fl::awake_data_;
int Fl::awake_ring_size_;
@@ -91,7 +88,7 @@ int Fl::add_awake_handler_(Fl_Awake_Handler func, void *data)
awake_data_ = (void**)malloc(awake_ring_size_*sizeof(void*));
}
if (awake_ring_head_==awake_ring_tail_-1 || awake_ring_head_+1==awake_ring_tail_) {
- // ring is full. Return -1 as ann error indicator.
+ // ring is full. Return -1 as an error indicator.
ret = -1;
} else {
awake_ring_[awake_ring_head_] = func;
@@ -278,7 +275,6 @@ void* Fl::thread_message() {
static void thread_awake_cb(int fd, void*) {
read(fd, &thread_message_, sizeof(void*));
- if (Fl::awake_cb) (*Fl::awake_cb)(thread_message_);
Fl_Awake_Handler func;
void *data;
while (Fl::get_awake_handler_(func, data)==0) {
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 4df22baae..94686a195 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -299,7 +299,6 @@ int fl_wait(double time_to_wait) {
if (fl_msg.message == fl_wake_msg) {
// Used for awaking wait() from another thread
thread_message_ = (void*)fl_msg.wParam;
- if (Fl::awake_cb) (*Fl::awake_cb)(thread_message_);
Fl_Awake_Handler func;
void *data;
while (Fl::get_awake_handler_(func, data)==0) {
diff --git a/test/threads.cxx b/test/threads.cxx
index 2c1424e42..15e8165ca 100644
--- a/test/threads.cxx
+++ b/test/threads.cxx
@@ -111,12 +111,6 @@ void* prime_func(void* p)
return 0;
}
-void message_cb(void *m) {
- if (m == (void *)browser1) putchar('1');
- else putchar('2');
- fflush(stdout);
-}
-
int main(int argc, char **argv)
{
Fl_Window* w = new Fl_Window(200, 200, "Single Thread");
@@ -141,11 +135,6 @@ int main(int argc, char **argv)
// when it is safe to do so...
Fl::lock();
- // Register a callback for Fl::awake() messages. This allows
- // you to get all thread messages even if you are in another
- // run loop (say, with a modal dialog...)
- Fl::set_awake_cb(message_cb);
-
// Start threads...
// One thread displaying in one browser
--
cgit v1.2.3