Albrecht Schlosser
2013-03-18 10:12:05 UTC
Hi all,
just to have confirmation of what I am doing.
My app is multithreaded ; the main() loop and some other working threads, receiving / sending data and doing calculations.
The question: what is the correct way to fire a graphics update from a thread ?
.....
static int fd_refresh[2];
.....
pipe(fd_refresh);
SetNonblocking(fd_refresh[0]);
SetNonblocking(fd_refresh[1]);
Fl::add_fd(fd_refresh[0], Do_refresh_callback, NULL);
.....
#define CMD_REFRESH 0
.....
static void Do_refresh_callback(int fd, void *data)
{
unsigned int val;
while(read(fd, &val, sizeof(val)) > 0)
{
switch(val)
{
// HERE I can draw to screen !
<nitpick on>just to have confirmation of what I am doing.
My app is multithreaded ; the main() loop and some other working threads, receiving / sending data and doing calculations.
The question: what is the correct way to fire a graphics update from a thread ?
.....
static int fd_refresh[2];
.....
pipe(fd_refresh);
SetNonblocking(fd_refresh[0]);
SetNonblocking(fd_refresh[1]);
Fl::add_fd(fd_refresh[0], Do_refresh_callback, NULL);
.....
#define CMD_REFRESH 0
.....
static void Do_refresh_callback(int fd, void *data)
{
unsigned int val;
while(read(fd, &val, sizeof(val)) > 0)
{
switch(val)
{
// HERE I can draw to screen !
To be precise: no, you can't!
</nitpick>
You can do widget updates and call redraw(), but you must not
call draw() methods directly from a callback. See also below.
break;
.....
}
}
.....
}
- A thread receives data and wants to update a drawing. It cannot do it directly,
so it writes to fd_refresh[1] an integer which values represent what I want to do
(full redraw(), partial updates, etc.) .
Fltk then will call Do_refresh_callback and there I will be safe drawing anything.
Is this sequence correct ?
Now it's working without (apparent) problems.
AFAICT this is okay, so long as you don't call draw() directly,.....
}
}
.....
}
- A thread receives data and wants to update a drawing. It cannot do it directly,
so it writes to fd_refresh[1] an integer which values represent what I want to do
(full redraw(), partial updates, etc.) .
Fltk then will call Do_refresh_callback and there I will be safe drawing anything.
Is this sequence correct ?
Now it's working without (apparent) problems.
as I wrote above.
However, using Fl::add_fd() with a pipe is not portable. IIRC you're
using an embedded Linux platform, so this may not be a problem for you.
But there are maybe more simple and portable ways using Fl::lock() and
Fl::awake() to send messages from a thread to the FLTK main loop to do
what you need. You can read more about this in the chapter "Advanced
FLTK" in the docs.
http://www.fltk.org/doc-1.3/advanced.html
Others will probably chime in and tell you more about programming with
threads and FLTK.
Albrecht