Currently, the `stop_func` is executed on an extra thread, and the
`g_context_specific_group_remove` function returns before the `stop_func`
finishes. It may happen that the `stop_func` is never executed if the
program terminates soon after calling it. Let's wait until the `stop_func`
is done.
Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/3258
Add SPDX license (but not copyright) headers to all files which follow a
certain pattern in their existing non-machine-readable header comment.
This commit was entirely generated using the command:
```
git ls-files gio/*.[ch] | xargs perl -0777 -pi -e 's/\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/\n \*\n \* SPDX-License-Identifier: LGPL-2.1-or-later\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/igs'
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1415
gio/gcontextspecificgroup.c: In function ‘g_context_specific_source_new’:
gio/gcontextspecificgroup.c:77:3: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
77 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from gobject/gbinding.h:28,
from glib/glib-object.h:22,
from gio/gcontextspecificgroup.h:23,
from gio/gcontextspecificgroup.c:22:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
GContextSpecificGroup has been somewhat broken for a rather long time:
when we remove the last reference on an object held in the group, we try
to clean up the source, but fail to actually remove it from the
mainloop.
We will soon stop emitting signals on the source (due to it having been
removed from the hash table) but any "in flight" signals will still be
delivered on the source, which continues to exist. This is a problem if
the event is being delivered just as the object is being destroyed.
This also means that we leave the source attached to the mainloop
forever (and next time will create a new one)...
This is demonstrated with the GtkAppChooser dialog which writes an
update to the mimeapps.list file just as it is closing, triggering the
app info monitor to fire just as it is being destroyed.
Karl Tomlinson correctly analysed the problem and proposed this fix.
https://bugzilla.gnome.org/show_bug.cgi?id=762994
For all of the effort spent ensuring that this algorithm would be
correctly threadsafe, I messed up the order of operations within a
single thread when porting to the new approach.
Fix that up.
Also: fix some overzealous asserting in the testcases. Since shutdown
is now lazy, we can never surely say !is_running at any particular point
in time.
There was a theoretical deadlock between the worker trying to emit a
signal at the same time as we were waiting for it to shutdown the
notification (while holding the lock).
The deadlock was particularly annoying because we didn't really need to
wait for the shutdown and because it wasn't possible to signals to
arrive while waiting for a start. Attempting to deal with start and
stop in an asymmetric way could have lead to other weird situations,
however.
Drop the lock while waiting for the worker thread to start. This means
that we face the possibility of multiple waiters on the cond at the same
time, so we need to make more of a state machine.
https://bugzilla.gnome.org/show_bug.cgi?id=742599
Add a new internal helper called GContextSpecificGroup.
This is a mechanism for helping to maintain a group of context-specific
monitor objects (eg: GAppInfoMonitor, GUnixMountMonitor).
https://bugzilla.gnome.org/show_bug.cgi?id=742599