Re: [g-a-devel]Sync SR Queue with ATSPI
- From: Michael Meeks <michael ximian com>
- To: Draghi Puterity <mp baum de>
- Cc: accessibility mailing list <gnome-accessibility-devel gnome org>, BAUM GNOME Development list <gnome-baum-dev basso SFBay Sun COM>
- Subject: Re: [g-a-devel]Sync SR Queue with ATSPI
- Date: 22 Jan 2002 17:33:42 +0000
Hi Draghi,
On Tue, 2002-01-22 at 14:07, Draghi Puterity wrote:
> We have introduced an async queue in SR core (from glib) in order be able to
> accept multiple input on different threads (ATSPI, Braille, Speech, etc).
Extraordiary - you really couldn't go for the non-blocking IO option ?
or did you not understand that ? it would still IMHO be far easier;
anyway.
> So we get/process the events on the same thread. Eventually we have
> something like this:
>
> // initialize sub components
> InitBraille(...);
> InitSpeech(...);
> InitSRL(...);
> // ....
>
> // enter main loop
> while (TRUE)
> {
> // get event from queue
> g_queue_pop (...);
>
> // process event
> // ...
> } ;
>
> We were facing the following design issue: sometimes before we enter the
> while loop we have to call SPI_Event_main in order to receive ATSPI events.
> The problem is, this function blocks (doesn't return).
What is the problem with it blocking ? I would at this point _really_
strongly suggest using non-blocking IO and a poll event driven mainloop
- as in linc. Really - not joking - really.
Anyway - as a broken sort of alternative we can implement some methods
to help you.
The problem is that any API for jamming mainloops together has acute
performance issues - the app sits there chewing 100% CPU, or adds nasty
latency problems.
So - caveats aside - since it seems you really don't want to do it by
non-blocking IO; the API is:
SPIBoolean SPI_eventIsReady (void);
AccessibleEvent *SPI_nextEvent (SPIBoolean waitForEvent);
Currently unimplemented; and worse - not easy to implement, and worse
almost certainly not what you want. IMHO a better API which we could
implement pretty quickly would be:
SPIBoolean SPI_mainIterate (SPIBoolean block);
which would simply process the events for you in the normal way -
invoking callbacks etc. as and when they occured, and return TRUE if
there was an event processed. So your program would sit there _belting_
around this little loop:
while (1) {
if (something_happened_on_some_other_thread)
do_something
while (SPI_mainIterate (FALSE));
}
> 1) The first idea was to call this function from another thread. We
> expected that in this case the ATSPI will call us back on that thread. Now
> that we have the async queue, this is not a problem for us any more but we
> suspect it might be for ATSPI as we might call its functions from another
> thread (our main thread, where we read the queue).
Ok; so one option that will work well is this:
a) Have all your umpteen threads
b) Each thread communicates with the main thread via a pipe
c) The main thread adds a poll on that file descriptor using eg.
LincWatch *linc_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data);
essentially hooking into the linc mainloop adding a watch, possibly you
don't want to hook into the mainloop - since this can give unexpected
re-enterancy, instead just add a glib GSource to the glib mainloop.
But - by the time you've done all that - you might as well be sitting
there polling on your input devices, doing non-blocking IO when data
arrives, and not using threads at all.
> 2) A second idea was to ask you to add a periodic callback to ATSPI in which
> we read/process our event queue, instead of having a main loop. We assumed
> that ATSPI will call us back in the correct thread so that we can make
> further ATSPI calls from it.
AT-SPI callbacks will enter in the thread that is running the mainloop
correct. In fact you _should_ be able to invoke other spi calls [ as
long as you don't plan to add / remove listeners / event handlers ] from
another thread - but you wander into a minefield of uncharted territory
and possibly serious undiscovered issues - still in fixing them you'll
improve the ORB :-)
> 3) Remus suggested a third possibility, as a variant of 2) through the
> function g_timeout_add which seems to get us out of SPI_Event_main by
> calling our callback on the ATSPI thread. This seems to work OK for our
> purposes, but we don't know if this approach is recomended and what other
> implication or side effects it might have on ATSPI.
The implication is that it gives the nasty side-effect of having a
latency slightly worse than whatever timeout you specify - or if you use
an idle handler of burning your laptop CPU off the board it's soldered
to ;-)
> Please tell us what you think about it.
Is it possible to see your code ?
Regards,
Michael.
--
mmeeks gnu org <><, Pseudo Engineer, itinerant idiot
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]