After the child sends the __delete__ message to the parent there is a period of
time in which the actor is registered, but the parent hasn't yet processed the
__delete__ message. During that time the parent can still try and send
messages to the child, but that will crash the child process. Fix this race by
making the child send a shutdown message to the parent, and have the parent
send __delete__ when it handles that message.
This is a bit dirty, we should be able to implement this just in the main
process by looking at the role of the children. However doing it this way is
simpler and allows us to share code with the non e10s case.
This is a bit dirty, we should be able to implement this just in the main
process by looking at the role of the children. However doing it this way is
simpler and allows us to share code with the non e10s case.
This is expected to happen when a accessible in the child process is shutdown,
but the parent calls a method with its ID before learning it has been shut
down.
DocAccessible::mAccessibleCache doesn't contain an entry for the document
itself so we need to handle it separately. The document always has ID 0, so we
can just check if that is the ID we are getting and if so just return the
document.
If we notify the parent process about new child documents before we
notify it of events it is possible the parent process's tree is out of
sync with ours, and doesn't contain the outer doc accessible for the new
document. SO we need to first notify the parent of changes in the
accessible tree for the document, and then we can notify it of new child
documents. We must also make sure when we serialize a subtree that is
being created to not include the sub document or its accessible tree.
We need to implement things like
https://developer.gnome.org/atk/unstable/AtkObject.html#atk-object-ref-state-set
and the same basic thing on windows. That API is fundamentally sync,
but the information necessary to implement it is only available in the
child process. That seems to leave us with two options, either we can
use sync ipc or we can use async ipc but spin a nested event loop. If
we were to spin nested event loops we'd have to be careful to make sure
a11y didn't do anything until the nested event loop was done, and then
a11y would have to deal with whatever changed. I'm not sure that will
work, and since the system is probably waiting for the accessibility
information anyway I don't think we get much out of spinning the event
loop. So I think its somewhat less bad to use sync ipc here.