This seems non-obvious to me. Document it.
It also seems important to know, because it means that the data pointer
might already be destroyed, before the source is unreferenced for good.
For example, if the data pointer keeps a reference to the GSource,
and it might seem sensible to call:
g_source_destroy(data->source);
g_source_unref(data->source); /* <<< data is already destroyed? */
This leads to a crash, if the source was attached to a context.
Since commit ab285899a6 ('gdbusconnection: Document main context
iteration for unsubscript'), we document when the user is guaranteed
that all resources are gone after g_dbus_connection_signal_unsubscribe().
This is not merely an implementation detail, it's something that the
user needs to be able to rely on. It is good that this is documented.
However, libnm does something different ([1]). It registers to several D-Bus
signals without providing a GDestroyNotify. After unsubscription, it schedules
another idle action with lower priority and uses that to know when
cleanup is complete. I think this is a useful alternative and should
also be guaranteed and documented to work.
Also note that this isn't just some implementation detail that currently
happens to work. GDBusConnection tightly integrates with GMainContext and it
works by scheduling idle sources with G_PRIORITY_DEFAULT priority. It needs to
schedule all events with this same priority, otherwise the ordering is not
preserved. At this point, with GDBusConnection working this way, this is no longer
something that can reasonably be any different. It's how GDBusConnection fundamentally
works, and a user must be able to rely on that. As such, this new promise isn't
something that we would want to break in the future.
Thus document it.
[1] a55c10c6cb/src/libnm-client-impl/nm-client.c (L7918)
Currently, `g_atomic_ref_count_inc ()` does three operations.
We try to get this down to one operation.
Fixed by replacing `g_atomic_int_inc ()` with `g_atomic_int_add ()`
which increments by 1 and returns old value
Note: changes current behaviour, checks are now done after increment.
Closes: #1583
SHGetSpecialFolderLocation() can cause 200ms delays when getting some
folder locations.
Also, use SHGetKnownFolderPath() normally, without loading it at runtime,
since GLib is Windows 7-or-later now.
Fixes#2397
tests/unicode-collate.c: In function ‘main’:
tests/unicode-collate.c:77:11: error: comparison of integer expressions of different signedness: ‘int’ and ‘guint’ {aka ‘unsigned int’}
77 | if (argc > i)
| ^
tests/timeloop.c: In function ‘read_all’:
tests/timeloop.c:41:21: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
41 | while (bytes_read < len)
| ^
tests/timeloop.c: In function ‘write_all’:
tests/timeloop.c:65:24: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
65 | while (bytes_written < len)
| ^
tests/slice-threadinit.c: In function ‘main’:
tests/slice-threadinit.c:77:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
77 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
tests/slice-threadinit.c:108:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
108 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
tests/slice-threadinit.c:113:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
113 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
tests/slice-threadinit.c:131:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
131 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
tests/slice-threadinit.c:139:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
139 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
tests/slice-threadinit.c:161:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
161 | for (j = 0; j < N_MAGAZINE_PROBES; j++)
| ^
I did it wrong last time... my bad...
tests/gobject/performance-threaded.c: In function ‘main’:
tests/gobject/performance-threaded.c:361:21: warning: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
361 | for (k = 1; k < argc; k++)
| ^
tests/mainloop-test.c: In function ‘cleanup_crawlers’:
tests/mainloop-test.c:358:15: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
358 | for (i=0; i < crawler_array->len; i++)
| ^
tests/dirname-test.c: In function ‘main’:
tests/dirname-test.c:105:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
105 | for (i = 0; i < n_dirname_checks; i++)
| ^
tests/gobject/performance-threaded.c: In function ‘run_test’:
tests/gobject/performance-threaded.c:302:19: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
302 | for (i = 0; i < n_threads; i++) {
| ^
tests/gobject/performance-threaded.c:308:19: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
308 | for (i = 0; i < n_threads; i++) {
| ^
tests/gobject/performance-threaded.c: In function ‘find_test’:
tests/gobject/performance-threaded.c:324:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
324 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
tests/gobject/performance-threaded.c: In function ‘main’:
tests/gobject/performance-threaded.c:351:21: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
351 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
tests/gobject/performance-threaded.c:369:21: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
369 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
tests/gobject/timeloop-closure.c: In function ‘read_all’:
tests/gobject/timeloop-closure.c:42:21: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
42 | while (bytes_read < len)
| ^
tests/gobject/timeloop-closure.c: In function ‘write_all’:
tests/gobject/timeloop-closure.c:66:24: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
66 | while (bytes_written < len)
| ^
tests/refcount/objects.c: In function ‘main’:
tests/refcount/objects.c:133:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘const unsigned int’}
133 | for (i = 0; i < n_threads; i++) {
| ^
tests/refcount/objects.c:149:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘unsigned int’
149 | for (i = 0; i < 2 * n_threads; i++) {
| ^
tests/gobject/performance.c: In function ‘find_test’:
tests/gobject/performance.c:1019:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
1019 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
tests/gobject/performance.c: In function ‘main’:
tests/gobject/performance.c:1054:21: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
1054 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
The actually parsed `@bytes` are not used because the only caller
does not provide an output parameter to request them. So this bug had
no effect in practice.
This fixes a bug where the family flag was ignored in lookup_data_new,
causing the resolver to call getaddrinfo with no hints set when clearly
the family hint should have been set.
tests/onceinit.c: In function ‘stress_concurrent_initializers’:
tests/onceinit.c:267:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
267 | for (i = 0; i < G_N_ELEMENTS (initializers); i++)
| ^