Re: [g-a-devel] ATK - Signal indicating new AtkObject creation.



Hi Willie, Michael, David,

I think we have ended up with a number of different object life-cycle
issues being discussed at the same time. I'll try and split them up, but
all in one e-mail. Sorry if i'm doing a very long-winded analysis.

Lazy accessible proxy creation
------------------------------

In a given application right now an accessible object looks something like:

GtkWidget <-- GailObject o-- AtkObject <-- IPCAdaptor <-- (Process
boundary) -- IPCProxy.

My initial e-mail was talking about the life-cycle of the GailObjects
and the IPCAdaptors.

In the D-Bus AT-SPI version we wanted to transfer lots of objects in one
go. GailObjects are still created lazily as far as Gtk is concerned, but
we FORCE their creation by traversing the tree of AtkObjects from the
top-level widget. Its important to remember that GailObjects are
referenced by their implementing GtkWidget, so there is no remote
reference counting issue here.

The life cycle of the IPCAdaptor is tied to the GailObject, they are
created in response to "child-added" signals and by traversing the
AtkObject tree from the root accessible.

What I was asking for was a fix for the ugliness of forcing creation of
the GailObjects and an easier way to create IPCAdaptors than traversing
the AtkObject tree whenever there are changes.

> There were at least some problems with this lazy creation AFAIR - I
> forget the precise details, but IIRC if eg. you get a focus signal, and
> then truly unref the currently focused object - it should go away, which
> then leaves you with a new and hence in-comparable object reference
> (that looks different), and of course if you truly un-ref it you don't
> get any signal notifications on the object: which is surprising.

I think this is true of the CORBA system. Comparisons are made based on
CORBA object reference. Wow, an actual reason why lazy creation of the
IPCAdaptor is a bad idea.

I think we just need some numbers on how much extra memory we are going
to use by doing this.

'Push' vs 'Pull'
----------------

This is how much of the accessible tree we transfer in one go. In CORBA
its one object at a time. In D-Bus is everything accessible in the
AtkObject tree. This isn't really an object life-cycle question. Its
more about the efficiency of the protocol.

> Keep in mind that not every AT needs to know the complete hierarchy.
> Orca right now, for example, tends only to look at localized areas
> (e.g., the object with focus).  With this, the notion in Orca was to
> treat the application itself as an off screen model rather than creating
> one locally.

I'm of the opinion that push everything will be most efficient, but I'm
distinctly lacking in proof of that. I'll need to do the performance
tests to make sure that this is really the best way. The overhead of one
big asynchronous call seems much better than lots of little method calls.

> An extra advantage is of course that the application itself can push
> great wodges of data asynchronously to the ATs without blocking or
> needing to respond to so many (any?) requests. That should reduce IPC
> pressure and improve performance in many cases [ I suspect ].

+1

The 'Infinite Space' problem
----------------------------

'Normal' Widgets under the CORBA version:

GtkWidget is owned by its parent widget (All the way up to the
top-level). GailObject is created and referenced by both its
implementing widget and the IPCAdaptor. The IPCAdaptor is remotely
referenced by the IPCProxy. So when the IPCProxy dissapears so does the
Adaptor, but the GailObjects stick around.

'Normal' Widgets under the D-Bus version:

GtkWidget unchanged. GailObjects are only referenced by their
implementing GtkWidget. The IPCAdaptor life-cycle is tied to the
GailObject. The IPCProxy in D-Bus land is a 'weak proxy'. They throw
exceptions if their implementing IPCAdaptor no longer exists.

I have a tough time deciding what to call 'non-normal' objects. But the
split I'm trying to make here is objects inside an infinite table,
inside a "manages-descendants" container, inside an infinite document.
The objects that exist because they are requested, rather than being
ultimately owned by a top-level widget.

In CORBA:

There isn't a problem, the GtkWidget is referenced by its GailObject
which is ultimately referenced remotely.

In D-Bus:

Big problem. There is no remote reference counting. The AtkObject is
created, referenced and never destroyed. Its a memory leak.

> Another thing to consider are objects that have the "manages
> descendants" property.  They can end up having a HUGE number of
> children, which are perhaps not even known until one scrolls to them.
> As such, creating accessible peers for the children of object that
> manage their descendants may be impossible.

> 
> 	But of course, this is a great plan. Ultimately, the whole nightmare I
> want to get rid of is the ref-counting life-cycle thing which is just
> terrible: and if cocked up can easily leave ever-growing application
> side leaks caused by badly behaved ATs (at least it could last I
> looked). If we get rid of that, we can be confident that there is a well
> defined, bounded memory usage, easily calculable from what is on-screen,
> and which is likely to be far smaller than the X server memory use to
> render the output on modern screens anyway :-)
> 

After reading these comments It made me realize that the much bigger
problem that needs sorting is the "infinite-space" one. Currently in the
D-Bus version this is broken. There is a huge memory leak.

> Or better we need to expose only what is on-screen, and expose a nice
> powerful table navigation API: "skip to next <Foo>" or whatever (also
> "get count of headings", "skip to heading <N>"). OTOH - those guys are
> going to be really efficient, and of course most applications are built
> around optimising screen rendering & thus surely shouldn't struggle to
> create a set of a11y peers for what is on-screen (?).
>

This would be my preferred solution. We don't worry about infinite
spaces because we don't let them exist. Only things on screen are made
accessible. They are all ultimately owned by the top-level widget. This
probably means adding a table navigation API as tables are where
infinites spaces exist? Perhaps some sort of cursor API for large documents?

The other option is to give up and add remote reference counting for
things that come under "manages-descendants".

Perhaps these should be split into separate threads. :/

Thanks

Mark


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]