Engine: track in progress watch handles to avoid spurious changed signals for the root path
When using the optimistic returning "fast" API, there is a case where a "changed" notification is emitted for the root path "/". This occurs as a result of the following sequence of events:
- The client subscribes to at least any path
- The engine returns immediately indicating to the client that the path is being watched, before it actually establishes a watch such that it will receive a message form the writer process when the relevant path changes.
- Some unrelated change is made to the database
- The watch request succeeds and the engine process receives a message indicating that the subscription has been created. At this point, the engine process cannot tell if it has failed to emit a changed notification to its clients, because something changed in the database in the time between when its client thought it was subscribed and when the engine process was actually subscribed. So, it emits a changed notification for the entire database, most of which has probably not changed.
This causes infinite loops and other intermittent and difficult to debug issues in client code such as gnome-shell and extensions. Changed signals cause subscription requests and subscription requests cause changed signals. Notably, it makes it impossible to run gnome-shell in valgrind, which complicates debugging memory issues.
Subscription requests should not cause changed signals, since they do not change the contents of the database.
The fix here makes the following changes:
- The engine stores a set of paths for which it has an active or pending subscription to
- If a client requests to subscribe to a path which the engine is already subscribed to, it does not subscribe to it a second time. This breaks the infinite loops, since clients generally only subscribe to a constant set of paths. The spurious change signals can now only happen before the first subscription completes.
- When a subscription confirmation message is received by the engine and the database has changed since the client was told the subscription was established, change notifications are sent only for the path being subscribed to, not for the root path.
There's an existing discussion on bugzilla here: https://bugzilla.gnome.org/show_bug.cgi?id=790640