Commit Graph

31836 Commits

Author SHA1 Message Date
Thomas Haller
7ed9816fbc gbinding: use g_object_weak_ref_full for bindings
The pattern here is that we acquire strong references via GWeakRef.
So you might think that g_object_weak_unref() is safe to call.

However, it is not safe, in case where another thread might run
g_object_run_dispose(). Which is clear, because GWeakRef only ensures we
hold a strong reference, but g_object_run_dispose() is anyway run on an
object where we already hold a reference.

In weak_unbind(), we obtain strong references, but (after) that
point, another thead might call g_object_run_dispose(). Then,
inside unbind_internal_locked() we do:

          g_object_weak_unref (source, weak_unbind, context);
          binding_context_unref (context);

Note that here weak_unbind might have already be unrefed, and
g_object_weak_unref() fails an assertion. But worse, the
weak_unbind callback will also be called and we issue two
binding_context_unref() and crash.

This is fixed by using g_object_weak_ref_full() (which handles the case
that the weak notification might have already be emitted) and a separate
GDestroyNotify (that is guaranteed to run exactly once).

This still doesn't make it fully work. Note that we also call

  g_signal_handler_disconnect (source, binding->source_notify);

this has exactly the same problem. A concurrent g_object_run_dispose()
will already disconnect all signal handlers, and calling disconnect
fails an assertion. I think the solution for that is a new API
g_signal_handler_try_disconnect(), which does not assert. After all, the
gulong signal ID is unique (the gulong is large enough to never wrap and
there is even a g_error() check against that).
2025-06-18 10:05:06 +02:00
Thomas Haller
7a795de4d6 gobject: new API with destroy notify for thread-safe use of g_object_weak_ref()
Add API g_object_weak_ref_full() and g_object_weak_unref_full().

The documentation elaborates how g_object_weak_ref() cannot be used
(naively) in a thread-safe way, when another thread is invoking dispose
(e.g. by running g_object_run_dispose() or by unrefing the last
reference). The suggestion is to combine that with GWeakRef.

Note that usually you cannot use GWeakRef alone, since you get no
notification when the reference count drop to zero. So a complete
solution uses g_object_weak_ref() and GWeakRef together.

The problem is that the user must not call g_object_weak_unref() when
another thread might just dispose() the instance. Presumably, they use
GWeakRef to first obtain a strong reference. That ensures that no other
thread can trigger dispose via a g_object_unref(). That however does not
help against another thread calling g_object_run_dispose().

In fact, there is no way to safely call g_object_weak_unref() when
another thread might call g_object_run_dispose() (unless the user
coordinates/synchronizes that at a higher level). The new API can avoid
that problem.

Note that calling g_object_weak_unref() asserts that it finds the
notification. Which might be violated by another thread calling
g_object_run_dispose() at the wrong time. But the assertion is not the
only problem. Often, the weak notification might hold resources (e.g.
an allocated data) that needs to be released -- either by the weak
notification callback or during g_object_weak_unref().

For example, see "gobject/gbinding.c". It calls `g_object_weak_unref
(source, weak_unbind, context);` while holding a strong reference on
source. But if another thread runs g_object_run_dispose() at the wrong
moment, we will call binding_context_unref() twice (and crash).

You might think, we cannot possibly support that another thread calls
g_object_run_dispose() while we still want to do something on an object.
Maybe in many cases that is not supportable. However, the user could
have a thread-safe GObject that handles that correctly. Also, see for
example GBinding, which operates on the basics of GObject (weak
notifications, GWeakRef, property notification subscription). Those
parts all all supposed to be thred-safe, and a low-level object like
GBinding should also work with objects that can be disposed by other
threads (including via g_object_run_dispose()). In general, while it's
often difficult to support multi threadded g_object_run_dispose(), the
basic g_object_weak_ref() should not fail to support such pattern.

Add new API that solves this. g_object_weak_ref_full() takes a
GDestroyNotify, which is guaranteed to be called exactly once -- unless
the data is stolen during g_object_weak_unref_full(). This can be
convenient for cleanup. But more importantly, doing the cleanup once is
also a place to synchronize and ensure we do something on the object,
while it is still alive.

We may combine g_object_weak_ref_full() with GWeakRef for a thread-safe
solution, like GBinding does. But you can now also have a fully
thread-safe solution without using GWeakRef. The benefit of that is that
you never need to acquire a strong reference on the object and never
emit a toggle notification, while still knowing the object is alive. The
unit test shows how that can be done.

The downside is that the size of WeakRefTuple increases by one pointer
size. Optimizing that would be cumbersome and is not done.
2025-06-18 10:00:04 +02:00
Thomas Haller
13caa01879 gobject: shrink WeakRefStack during release-all
It feels ugly to leave the buffer not sized right.

We call g_object_weak_release_all() during g_object_real_dispose() and
right before finalize. In most cases, we expect that the loop iterates
until there are no weak notifications left (in which case the entire
WeakRefStack is freed). In that case, there is no need to shrink the
buffer, because it's going to be released soon anyway.

Note that no new weak references can be registered after finalize (as
the ref count already dropped to zero). However, new weak referenes can
be registered during dispose (either during the last g_object_unref() or
during g_object_run_dispose()).

In that case, I feel it is nice to bring the buffer size right again. We
don't know how long the object will continue to live afterwards, so
let's trim the extra allocation.
2025-06-18 10:00:04 +02:00
Thomas Haller
e3c36bacfc gobject: clean up loop in g_object_weak_unref_cb()
Refactor the function to separate the search and removal logic. Instead
of nesting the removal inside the loop, first search for the matching
entry. If none is found, return early. Otherwise, goto the removal
logic.

This reduces indentation, emphasizes the main path, and improves
readability and maintainability. The change uses the often unfairly
maligned goto for clarity.
2025-06-18 10:00:04 +02:00
Philip Withnall
dc6f9447cd Merge branch 'g_match_info_fetch_pos_desc' into 'main'
docs: clarifying return values from g_match_info_fetch_pos

Closes #2848

See merge request GNOME/glib!4664
2025-06-17 13:07:04 +00:00
Mark Lautman
bd36359ed8 docs: clarifying return values from g_match_info_fetch_pos
Details the returned function value, start_pos, and end_pos for various scenarios of capture parenthesis and GMatchInfo.

Closes #2848
2025-06-17 13:07:04 +00:00
Philip Withnall
f0f1c64c5b Merge branch 'fix-do-not-queue-docs' into 'main'
gio: enums: Fix GBusNameOwnerFlags's annotation

See merge request GNOME/glib!4665
2025-06-17 10:39:46 +00:00
Maximiliano Sandoval
d02f59a54b gio: enums: Fix GBusNameOwnerFlags's annotation
g-ir-scanner won't pick Since or Deprecated annotations if they are
inlined, they need a dedicated documentation block for this to work. The
since annotation is used, e.g. in gtk-rs, to not expose enum flags if
not compiled declaring we have a new enough glib version.
2025-06-16 17:57:53 +02:00
Philip Withnall
c1e8174992 2.85.1
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2.85.1
2025-06-13 12:28:00 +01:00
Philip Withnall
e897df0e45 Merge branch 'gio-unix-docs-fix' into 'main'
docs: Stop hiding the Unix-like APIs which are in Gio-2.0.gir

See merge request GNOME/glib!4657
2025-06-13 11:03:37 +00:00
Philip Withnall
96aa5f1b1f Merge branch 'check-recursive-trashing' into 'main'
glocalfile: Verify deleting from trash beforehand

Closes #1665

See merge request GNOME/glib!4653
2025-06-12 16:01:15 +00:00
Philip Withnall
0bd51d8f8b Merge branch 'meson-use-localedir-opt' into 'main'
meson: Use the appropriate localedir option

See merge request GNOME/glib!4661
2025-06-12 12:20:03 +00:00
Ignacy Kuchciński
181992ccb5 glocalfile: Verify deleting from trash beforehand
Verify that you can delete the file from the trash before moving it, if
the file is a directory owned by the user, recursively check for
non-empty directory not owned by he user.

Closes https://gitlab.gnome.org/GNOME/glib/-/issues/1665
2025-06-12 13:26:22 +02:00
Kleis Auke Wolthuizen
0cbb5fb378 meson: Use the appropriate localedir option 2025-06-11 15:56:27 +02:00
Ignacy Kuchciński
2a7f28e88a glocalfile: Populate different statbuf for parent
Populate a different statbuf for the parent directory, so that we can
keep using file_state for the file we're removing later in the code.
2025-06-11 10:33:50 +02:00
Philip Withnall
50a35a4a81 Merge branch 'sync-gnulib' into 'main'
glib/gnulib/printf.c: Sync with gnulib

See merge request GNOME/glib!4560
2025-06-10 13:55:12 +00:00
Philip Withnall
d29cc3892f Merge branch 'make-sysprof-yield' into 'main'
Make the sysprof feature yield

See merge request GNOME/glib!4659
2025-06-09 12:53:11 +00:00
Matthias Clasen
c915502eb8 build: Make the sysprof feature yield
This is expected by other projects who use glib as a subproject,
and there is little point in making the option a feature unless
you inherit it.
2025-06-07 23:53:19 -04:00
Philip Withnall
a6445ee3c4 Merge branch 'mcatanzaro/gmarkup-documentation' into 'main'
gmarkup: make documentation more discoverable

See merge request GNOME/glib!4658
2025-06-03 14:00:15 +00:00
Michael Catanzaro
27aad582f2 gmarkup: make documentation more discoverable
There is a bunch of documentation in a separate markdown page that does
not appear in search results. We should point to it.

I think the restriction on not being used to process untrusted input
should be relaxed into something more permissive, like "should not be
used on untrusted input if you care about denial of service." But that
can be a problem for another day.
2025-06-03 14:00:15 +00:00
Philip Withnall
3d84aa264c docs: Stop hiding the Unix-like APIs which are in Gio-2.0.gir
There are four `Unix.+` classes in `Gio-2.0.gir` which need to be
exposed in the `Gio-2.0.gir` docs because they are actually now
cross-platform (which is a move which has caused a lot of pain).

Change the code which filters out the rest of the `Unix.+` classes to
ignore these ones. The rest of the classes continue to be documented via
`GioUnix-2.0.gir`.

Changing the regexs for this involved a fun use of negative lookahead.

See https://gitlab.gnome.org/GNOME/glib/-/issues/3697#note_2459405

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3697
2025-06-03 14:10:52 +01:00
Philip Withnall
36a34e0d33 Merge branch 'string-overflow-check' into 'main'
gstring: Fix overflow check when expanding the string

See merge request GNOME/glib!4655
2025-06-03 12:07:10 +00:00
Philip Withnall
33d9ba2fcc gstring: Fix overflow check when expanding the string
After commit 34b7992fd6 the overflow check
was only done when expanding the string, but we need to do it before
checking whether to expand the string, otherwise that calculation could
overflow and falsely decide that the string is big enough already.

As a concrete example, consider a `GString` which has:
 * `.len = G_MAXSIZE / 2 + 1`
 * `.allocated_len = G_MAXSIZE / 2 + 1`
and `g_string_append()` is called on it with an input string of length
`G_MAXSIZE / 2`.

This results in a call `g_string_maybe_expand (string, G_MAXSIZE / 2)`,
which calculates `string->len + len` as `(G_MAXSIZE / 2 + 1) +
(G_MAXSIZE / 2)` which evaluates to `1` as it overflows. This is not
greater than `string->allocated_len` (which is `G_MAXSIZE / 2 + 1`), so
`g_string_expand()` is *not* called, and `g_string_maybe_expand()`
returns successfully. The caller then assumes that there’s enough space
in the buffer, and happily continues to cause a buffer overflow.

It’s unlikely anyone could hit this in practice because it requires
ludicrously big strings and `GString` allocations, which likely would
have been blocked by other code, but if we’re going to have the overflow
checks in `GString` then they should be effective.

Spotted by code inspection.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-06-03 11:31:04 +01:00
Kleis Auke Wolthuizen
044df5b2bb glib/gnulib/printf.c: Sync with gnulib
Sync _g_gnulib_vsprintf() with lib/vszprintf.c and
_g_gnulib_vsnprintf() with lib/vsnzprintf.c from gnulib, plus adjust
the final guards to handle differing return signatures.

Highlights:
- Avoid a memory allocation if the result fits into the provided
  buffer.
  https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commit;h=f5200a50fa42fdaed40ecc67b27f41be328a6a01
- Don't assume vasnprintf returns EOVERFLOW if the size exceeds
  INT_MAX; do the check ourselves.
  https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commit;h=7e421d1cd6a8752aa527895c759a72a47203959a
2025-06-01 10:10:32 +02:00
Philip Withnall
8825c164ea Merge branch 'libglib-static-dep-for-tests' into 'main'
Meson: Add libglib_static dependency for use in tests

See merge request GNOME/glib!4651
2025-05-30 22:15:31 +00:00
Philip Withnall
80ca73f501 Merge branch 'mcatanzaro/string-test' into 'main'
Fix buffer overflow in string-test

See merge request GNOME/glib!4654
2025-05-30 21:03:38 +00:00
Michael Catanzaro
e585ea2a7d Fix buffer overflow in string-test
This string is 24 bytes long, not 25 bytes. This problem was noticed by
a bug hunter running the testsuite under address sanitizer.
2025-05-30 14:59:03 -05:00
Philip Withnall
c1ff515f09 Merge branch 'gregex_description_update' into 'main'
GRegex: update class description

See merge request GNOME/glib!4646
2025-05-30 11:39:50 +00:00
Mark Lautman
2ab485a472 GRegex: update class description
See merge request 4643
2025-05-30 11:39:50 +00:00
Philip Withnall
b7ce23703e Merge branch 'improve-gvaluesetboxed-docs' into 'main'
gobject: clarify in documentation that g_value_set_boxed copies

See merge request GNOME/glib!4652
2025-05-30 10:01:13 +00:00
Marco Trevisan
45869df93c Merge branch 'regex-docs' into 'main'
gregex: Clarify docs for end_pos

See merge request GNOME/glib!4645
2025-05-30 11:48:33 +02:00
Pablo Correa Gómez
bf24002428 gobject: clarify in documentation that g_value_set_boxed copies
This comes as a consequence of confusion by two devs[1]. The wording
is copied from g_value_set_string, which is more clear on what the
function is doing with the object it's consuming.

[1] https://gitlab.gnome.org/GNOME/Incubator/papers/-/merge_requests/467#note_2455770
2025-05-29 23:46:19 +02:00
Luca Bacci
e2dfe27996 Add specific test for private functions 2025-05-29 16:45:39 +02:00
Luca Bacci
08a79f4465 Meson: Enable tests for internal functions 2025-05-29 16:45:39 +02:00
Luca Bacci
5cc32c35f9 Meson: Add glib static dependency
This dependency can be used to link with GLib object files.
2025-05-29 16:45:33 +02:00
Philip Withnall
2db24eeef0 Merge branch 'fopen-cloexec' into 'main'
gstdio: Add support for the `e` flag (O_CLOEXEC) to g_fopen()

See merge request GNOME/glib!4564
2025-05-29 10:59:56 +00:00
Luca Bacci
f2b98de002 Use TLS callback also for shared library builds
This way things just work even if the compiled object
files are used in tests.
2025-05-29 12:41:29 +02:00
Philip Withnall
b2f0bb9592 tests: Expand PATH for Python tests on Windows
This works around a Meson bug
(https://github.com/mesonbuild/meson/issues/4668).

If we have a Python test which spawns a built native binary, that binary is
listed in the `depends` argument of the `test()`. On Linux, this results in
the directories containing the built libraries which the binary depends on
being added to the `LD_LIBRARY_PATH` of the test invocation. On Windows,
however, Meson currently doesn’t add those directories to `PATH` (which is
the equivalent of `LD_LIBRARY_PATH`), so we have to do it manually.

This takes the same approach as Christoph Reiter did in
gobject-introspection
(13e8c7ff80/tests/meson.build (L2)).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-28 16:10:55 +01:00
Philip Withnall
306abedea5 tests: Add tests for new e modes for g_fopen()
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-28 16:10:48 +01:00
Philip Withnall
ac2ecb5a43 tests: Add e flag to fdopen() calls in gsubprocess tests
Unlike the previous commit, there is no `g_fdopen()` wrapper where we
can add cross-platform support for this.

I’m not adding that now just for `O_CLOEXEC` support for these two
calls, so pass the flag locally for now.

If someone wanted to add a `g_fdopen()` wrapper in future, the
`GLIB_FD_CLOEXEC` here could be refactored easily.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-28 14:37:08 +01:00
Philip Withnall
f9a7ac11f5 gstdio: Add support for the e flag (O_CLOEXEC) to g_fopen()
This adds cross-platform support for it: on glibc, musl and BSD’s libc,
the flag is natively supported. On Windows, convert it to the `N` flag,
which similarly indicates that an open file shouldn’t be inherited by
child processes.

This allows us to unconditionally pass `e` to `g_fopen()` so `O_CLOEXEC`
can easily be set on its FDs.

Also do the same for `g_freopen()`, since it shares the same underlying
mode handling code.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-28 14:37:02 +01:00
Philip Withnall
a672b11024 Merge branch 'wip/chergert/fix-3664' into 'main'
girepository: add singleton GIRepository back

Closes #3664

See merge request GNOME/glib!4630
2025-05-28 12:18:47 +00:00
Michael Catanzaro
9f5a4a4c50 Merge branch 'async-queue-tests-threading' into 'main'
tests: Add atomics to asyncqueue test global variables

See merge request GNOME/glib!4650
2025-05-27 14:14:55 -05:00
Philip Withnall
f447dfa3cd Merge branch 'pr-2025-05-24-asyncqueue-doc' into 'main'
GAysncQueue: use transfer full annotations

Closes #3698

See merge request GNOME/glib!4648
2025-05-27 14:21:59 +00:00
Philip Withnall
66e4f48b69 Merge branch 'mr-2025-05-24-assert-insert-sorted' into 'main'
GAsyncQueue: assert non-null data in push_sorted()

See merge request GNOME/glib!4649
2025-05-27 13:14:04 +00:00
Philip Withnall
4c05dae76e tests: Fix line wrapping in a function definition in asyncqueue
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-27 13:17:52 +01:00
Philip Withnall
7e225eaeb3 tests: Add atomics to asyncqueue test global variables
While the test is structured so that each member of these arrays is only
ever accessed by one worker thread, there’s currently no barriers to
synchronise the final read (in the main thread) with the final write (in
a worker thread), which could lead to very occasional failures like this
one (https://gitlab.gnome.org/GNOME/glib/-/jobs/5119324):
```
GLib:ERROR:../glib/tests/asyncqueue.c:203:test_async_queue_threads: assertion failed (sums[i] > 0): (0 > 0)
not ok /asyncqueue/threads - GLib:ERROR:../glib/tests/asyncqueue.c:203:test_async_queue_threads: assertion failed (sums[i] > 0): (0 > 0)
```

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-05-27 13:17:45 +01:00
Alicia Boya García
8dc4df894e GAsyncQueue: assert non-null data in push_sorted()
While working on
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4648
I realized there is no assertion checking the data argument in either
g_async_queue_push_sorted() or g_async_queue_push_sorted_unlocked().

All the other push functions assert that data is not null, and the
argument is even marked as not nullable in g_async_queue_push_sorted(),
so this is clearly an oversight.

This patch adds the assert in the _unlocked() version, so that it
applies to both.

I have consciously separated this change from the other merge request,
since that one only makes documentation changes, whereas adding an
assert is a subtle change in behavior that could potentially show as
a regression in buggy applications.
2025-05-24 16:43:47 +02:00
Alicia Boya García
71dd49bd8a GAysncQueue: use transfer full annotations
Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/3698

This patch marks the data arguments of the push() methods and the return
values of the pop() methods as transfer full.

This patch also marks the return values of the non-timed pop() functions
as non-nullable, as they can only return NULL when assertions fail.

In the process I also found g_async_queue_push_sorted_unlocked() was
missing a non-nullable annotation, so I added it. Given that
g_async_queue_push_sorted() has a non-nullable annotation, it makes no
sense for the unlocked version to lack it.
2025-05-24 16:32:50 +02:00
Christian Hergert
690ba3b7b5 girepository: add singleton GIRepository back
This is needed to avoid situations where you cannot coordinate between
bindings and libraries which also need to interact with introspection
which could affect bindings.

For example, a Python application using libpeas to load plugins, also in
Python.

Fixes: #3664
2025-05-23 13:52:37 -07:00