Re: [g-a-devel]Sync SR Queue with ATSPI



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]