|
From: <tim...@en...> - 2007-05-07 18:08:07
|
Dear gnuplot (especially on MacOS) enthusiasts,
Dear Joe, Mojca, who tested wxt on MacOS since its early ages ;),
Dear Nigel, whose remarks inspired me for this mail,
I have worked a little more on wxt for MacOS this last days.
Fixing it for MacOS is not really straightforward, because I seem to
have abused Linux/GTK/X flexibility so that some things have to be
restricted now.
The main restriction, as discussed in previous mails, is that the main
thread should do each and every GUI action. Currently, wxt uses a second
thread for the GUI event loop, and happily does things in the first
thread with some mutexes locked. This approach does not work on MacOS.
1st solution, as suggested previously = use two processes:
- this is the design of the x11 terminal. I don't like it, because I
find complicated to have to handle two processes and their
inter-communication where we really have one program (one task).
2nd solution = invert the threads' roles (i.e. the shortest path from
where we are now):
- the main thread runs the GUI event loop, and gnuplot gnu_main()
(plot.c:278) runs in the second thread.
- terminal callbacks (such as term->graphics, term->text) do every GUI
action asynchronously, by posting messages to the GUI event loop
- corner cases:
*signals masks have to be carefully set, so that ^C ends up in the
second thread (easy)
*doing everything asynchronously can be painful, sometimes it's
actually synchronous, so you have to wait for the other thread to finish
before continuing (I am thinking of term->init() where new windows are
created) (easy, but not really beautiful programming)
* this adds a startup overhead, because wxWidgets has to be
initialized at launch-time for the threads facility (I don't see how to
switch the two thread contexts when they are already running) (currently
it's initialized when first used).
3rd solution = use one thread only (the most ambitious)
- the one and only thread is an event loop.
- "a char arrived on stdin" is handled as an event (this is natural,
isn't it?), and passed to readline
- the event loop is actually the GUI loop, just extended to watch stdin
in addition to window events
- no more locking, no more worries about not-so-asynchronous actions,
no more multithreading restrictions to take care of
- it looks like it's the way Nigel Nunn has mentioned for so long
- drawbacks:
* it's the longer way to go from what we have now, involving some
work in some mechanisms and assumptions gnuplot has had since the early
ages probably.
* as for the previous solution, there's a startup overhead because
we would have to initialize the event loop (i.e. wxWidgets)
Currently, we have:
while( readline(); do_line(); ) {};
Instead we would have an event loop, with the following callbacks:
data_is_available_in_stdin() {rl_callback_read_char ();}
line_is_completed() {do_line();}
The event loop naturally processes these events exactly the same way it
does with others, namely GUI events.
In practise, a lot of reorganization is needed:
- in plot.c, to separate the initialization code, from the actual loop
quoted above,
- in command.c and readline.c, to implement the event-based approach,
and to rework the pieces of code that call read_line or getc directly
(builtin-pager, help system, inline data)
So, I'd like to know what you think of this. Do you think it's worth
doing all these changes ? Note that if I work on this, I won't change
the way it works when wxt is not compiled in.
Best regards,
Timothée Lecomte
|