Commit Graph

29310 Commits

Author SHA1 Message Date
Thomas Haller
cf044ba7ad gobject: use per-object bit-lock instead of global mutex for notify-queue 2024-01-04 16:32:09 +01:00
Thomas Haller
c66880e46f gobject: use per-object bit-lock instead of global mutex for weak-refs 2024-01-04 16:32:09 +01:00
Thomas Haller
bfb829231f gobject: never access optional flags without atomic
The optional flags should be used for bit locks. That means,
we must only use atomic operations when updating the flags.

Having a variant of _X methods that update the flags without
locks (_X), means that we must take care not to take bit locks
during construction.

That is hard to get right. There is so much happening during object
construction, that it's unclear when it's really safe to access the
flags without atomic. Don't do this.
2024-01-04 16:32:09 +01:00
Thomas Haller
777606d9c4 gobject: add private data for GObject and use it for optional flags
Add a GObjectPrivate struct and let GObject have private data.

On architectures where we have an alignment gap in GObject struct (64
bit), we use the gap for "optional_flags". Use the private data for
those optional flags, on architectures where we don't have them.

For now, private data is only added for those optional flags (and not on
architectures, where the flags fit inside GObject). In the future, we
may add additional fields there, and add the private struct always.

The main purpose will be to replace all the global locks with per-object
locks, and make "optional_flags" also available on 32bit.
2024-01-04 16:32:09 +01:00
Thomas Haller
a12f0731dd glib: add internal macro G_THREAD_LOCAL for support for thread local storage
_Thread_local is also C11, so possibly other compilers would also support
it.

However, since not *all* compilers support it, it can anyway only be
used as optimization and conditional asserts. As such, the current
detection based on __GNUC__ to only support gcc (and clang) is good
enough.
2024-01-04 16:32:09 +01:00
Thomas Haller
6c389738d3 gobject/tests/reference: add tests for concurrent g_weak_ref_set()
GWeakRef methods are thread safe. Add test for calling g_weak_ref_set()
concurrently.
2024-01-04 16:32:09 +01:00
Thomas Haller
787861761d gobject/tests/reference: add test for deadlock related to GWeakRef and toggle reference
GWeakRef calls g_object_ref() while holding a read lock.
g_object_ref() can emit a toggle notification.

If you then inside the toggle notification setup a GWeakRef
(to the same or another object), the code will try to get
a write lock. Deadlock will happen.

Add a test to "show" that (the breaking part is commented out).
Will be fixed next.
2024-01-04 16:17:13 +01:00
Philip Withnall
dd2b6d7e3f Merge branch 'th/g-object-unref-ref' into 'main'
[th/g-object-unref-ref] fix race in g_object_unref()

Closes #3064

See merge request GNOME/glib!3769
2024-01-03 23:39:24 +00:00
Philip Withnall
4663307374 Merge branch 'datetime-docs' into 'main'
gdatetime: Fix title of documentation comment

See merge request GNOME/glib!3789
2024-01-03 13:47:22 +00:00
Emmanuele Bassi
9edfeb1e89 Merge branch 'pspec-pool-test-leak' into 'main'
tests: Fix a minor leak in the new GParamSpecPool test

See merge request GNOME/glib!3799
2024-01-03 12:47:44 +00:00
Philip Withnall
bf7ccbde9e tests: Fix a minor leak in the new GParamSpecPool test
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-01-03 12:04:16 +00:00
Simon McVittie
e9c1dc1aa7 Merge branch 'wip/smcv/girepository-must-be-3.0' into 'main'
girepository: Skip GIRepository versions not matching GIRepository-3.0

See merge request GNOME/glib!3795
2024-01-02 13:20:14 +00:00
Michael Catanzaro
579446f1eb Merge branch '3037-drop-gitignore' into 'main'
docs: Drop outdated .gitignore files

See merge request GNOME/glib!3798
2024-01-01 14:16:03 +00:00
Philip Withnall
caf57bac0c docs: Drop outdated .gitignore files
These are no longer relevant since dropping gtk-doc.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3037
2024-01-01 12:50:12 +00:00
Philip Withnall
545cac6156 Merge branch 'gtype-rand-boxed' into 'main'
Add boxed GType for GRand

See merge request GNOME/glib!3794
2023-12-31 09:09:49 +00:00
Tanmay
dbbd9c60ba Add boxed GType for GRand
Signed-off-by: Tanmay Patil <tanmaynpatil105@gmail.com>
2023-12-31 09:09:48 +00:00
Philip Withnall
fc3aad1661 Merge branch 'ebassi/rst-codegen-short-title' into 'main'
Shorten the title for D-Bus interface docs

See merge request GNOME/glib!3793
2023-12-31 09:08:20 +00:00
Thomas Haller
35e7fec16c stp: add code comment to gobject.object_unref about object being dangling 2023-12-30 00:20:17 +01:00
Thomas Haller
f4aa119157 gobject: really fix race with GWeakRef during g_object_unref()
To do it really race-free, we must take a reader lock during when
decrementing the ref count from 1 to 0.
2023-12-30 00:20:17 +01:00
Thomas Haller
2952cfd7a7 gobject: drop clearing quark_weak_locations from g_object_real_dispose()
In g_object_unref(), we call _object_unref_clear_weak_locations() before
and after dispose() already. At those places it is necessary to do.

Calling it a third time during g_object_real_dispose() seems not useful,
has unnecessary overhead and actually undesirable.

In particular, because g_object_real_dispose() is the implementation for
the virtual function GObject.dispose(). For subclasses that override dispose(),
it's not well defined at which point they should chain up the parent
implementation (for dispose(), I'd argue that usually they chain up at
the end of their own code). If they chain up at the end, this has no
effect.

This only really matters if you try to register GWeakRef during dipose
and/or resurrect the object.

        static void dispose(GObject *object)
        {
            g_weak_ref_set(&global_weak_ref, object);
            global_ref = g_object_ref(object);
            G_OBJECT_CLASS (parent_class)->dispose (object);
        }

the object was resurrected, but g_object_real_dispose() would clear the
weak ref. That is not desirable, nor does it make sense.

Instead, the virtual function dispose() is called from two places, from
g_object_unref() and g_object_run_dispose(). In both cases, it is
ensured that weak locations are cleared *after* dispatching the virtual
function. Don't do it somewhere in the middle from
g_object_real_dispose().
2023-12-30 00:20:17 +01:00
Simon McVittie
e6c8c75ccc girepository: Skip GIRepository versions not matching GIRepository-3.0
A few applications such as gnome-music load the GIRepository typelib
and use it to adjust their search paths.

GLib 2.79.x now provides libgirepository-2.0.so.0 (GIRepository-3.0),
but each OS distribution is likely to have a transitional period during
which GLib's libgirepository-2.0.so.0 has become available, but bindings
like PyGI and gjs are still linked to gobject-introspection's
libgirepository-1.0.so.1 (GIRepository-2.0).

During this transitional period, interpreted languages that load the
GIRepository namespace could get the "wrong" version, which will result
in adjusting a search path that will not actually affect the language
binding's typelib lookup, and could also lead to symbol and type-system
conflicts.

We can avoid this collision by making GLib's GIRepository library refuse
to load versions of the GIRepository typelib that are not 3.0, and
similarly making gobject-introspection's GIRepository library refuse to
load typelib versions that are not 2.0. A relatively neat way to achieve
that is to make each version behave as if the other one doesn't exist.

Signed-off-by: Simon McVittie <smcv@debian.org>
2023-12-29 15:45:02 +00:00
Emmanuele Bassi
2b2b04d188 Shorten the title for D-Bus interface docs
The title of an interface can be arbitrarily long, considering that
reverse DNS namespaces can be pretty complex. Instead of using the whole
interface name, we can use the name without the prefix.
2023-12-29 01:02:00 +00:00
Thomas Haller
fe0347bc64 gobject: fix race clearing weak locations for resurrection during g_object_unref()
dispose() can resurrect an object and/or register a weak-ref. After
returning from dispose(), we must check again. And we must do so in a
race-free manner, where we check that we have no more weak-locations
and the ref-count is one.

In fact, if _object_unref_clear_weak_locations() determines that the
ref-count is 1, it must also decrement the ref-count to zero while
holding the weak_locations_lock. This prevents g_weak_ref_set() to
still register a weak-pointer after the reference count dropped to zero.

Also add an assertion to g_weak_ref_set(), that the object is still
alive. The assertion is useful to finding bugs, but the change really
makes it impossible that a wrongly used g_weak_ref_set() can still
resurrect the object after finalization starts.

The final

    g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);

during finalization is no longer necessary and dropped.
2023-12-28 09:36:56 +01:00
Thomas Haller
aaf4ccb901 gobject: avoid calling g_weak_ref_set() when intializing GWeakRef to NULL
If object is NULL, g_weak_ref_set() really does nothing. However,
it will pointlessly take a lock, before deciding to do nothing.
Avoid that.
2023-12-28 09:36:56 +01:00
Thomas Haller
de5e26e2ed gobject: remove unused quark_weak_refs from gobject
We never set any data for quark_weak_refs. It's unused, drop it.

Also, fail a g_critical() assertion, if the GWeakRef is unexpectedly not
registered in the object. That really shouldn't happen.
2023-12-28 09:36:56 +01:00
Thomas Haller
9ae43169cf gobject: fix race in toggle ref during g_object_ref()
Previously:

   1. old_val = atomic_add(&object->ref_count);
   2. if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object)) { toggle_notify() }

As old_val was 1, you might think that no other thread can have a valid
reference to object. However, that's not the case. For one, GWeakRef can
be used to create another strong reference. More easily, the single
reference can be shared between multiple threads (as long as the code
takes care that the object lives long enough).

That means, another thread can easily add and drop references (including
toggle references). All between step 1 and 2.

A race here might be hard to hit, and the effect might not be obviously
bad. However, consider old_val is 1 due to a normal reference, and
another thread adds a toggle ref between step 1. and 2. Then we would
notify a toggle from 1->2, although a newly added toggle ref is expected
to always start with a normal and a toggle reference. The first toggle
notification is expected to notify about the loss of other references, not
about getting a second reference.

To handle this properly, when we increase the reference count from 1 to
2, we must do so under a lock and check for the toggle notification.

As we now correctly track the toggle behavior, we can also assert in
toggle_refs_get_notify_unlocked() that n_toggle_refs agrees with the
number of references, that is, that the user did always match
g_object_add_toggle_ref() with g_object_remove_toggle_ref().

The downside is here too, that there is now a case (when increasing the
reference count from 1 to 2)  where we need to take the global lock.
That performance problem should be addresses by using per-object locks
instead of a global lock.
2023-12-28 09:36:56 +01:00
Thomas Haller
408dc69186 gobject: fix race in g_object_unref() related to toggle references
The previous g_object_unref() was racy. There were three places where we
decremented the ref count, but still accessed the object afterwards
(while assuming that somebody else might still hold a reference). For
example:

      if (!g_atomic_int_compare_and_exchange_full ((int *) &object->ref_count,
                                                   old_ref, old_ref - 1,
                                                   &old_ref))
        continue;

      TRACE (GOBJECT_OBJECT_UNREF (object, G_TYPE_FROM_INSTANCE (object), old_ref));

      /* if we went from 2->1 we need to notify toggle refs if any */
      if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
        {
          /* The last ref being held in this case is owned by the toggle_ref */
          toggle_refs_notify (object, TRUE);
        }

After we decrement the reference count (and gave up our reference), we
are only allowed to access object if we know we have the only possible
reference to it. In particular, if old_ref is larger than 1, then
somebody else holds references and races against destroying object.
The object might be a dangling pointer already.

This is slightly complicated due to toggle references and clearing of
weak-locations.

For toggle references, we must take a lock on the mutex. Luckily, that
is only necessary, when the current reference count is exactly 2.

Note that we emit the TRACE() after the ref count was already decreased.
If another thread unrefs the object, inside the TRACE() we might have a
dangling pointer. That would only be fixable, by emitting the TRACE()
before the actual unref (which has its own problems). This problem
already existed previously.

The change to the test is necessary and correct. Before this patch,
g_object_unref() would call dispose() and decrement the reference count
right after.
In the test case at gobject/tests/reference.c:1108, the reference count
after dispose and decrement is 1. Then it thaws the queue notification,
which emits a property changed signal. The test then proceeds to
reference the object again and notifying the toggle reference.
Previously, the toggle reference was notified 3 times.
After this change, the property changed signal is emitted before
decreasing the reference count. Taking a reference then does not cause
an additional toggle on+off, so in total only one toggle happens.
That accounts for the change in the test. The new behavior is
correct.
2023-12-28 09:36:56 +01:00
Thomas Haller
7292726931 gobject: reformat g_object_ref()/g_object_unref() with clang-format
The indentation level in g_object_unref() is wrong. Fix it by reformatting
the function with clang-format. That makes follow up patches easier to adhere
a consistent style.

No other changes.
2023-12-28 09:36:56 +01:00
Thomas Haller
b2a68d6ec4 gobject: factor out toggle_refs_get_notify_unlocked() function
This is the part of toggle_refs_notify(), for which we usually hold the
lock. It will be used next.
2023-12-28 09:32:49 +01:00
Thomas Haller
2276099236 gobject: remove data when last toggle ref is removed
Toggle refs are seldom used, and when they are, it makes mostly sense that
there is only one of them. Thus, when removing the last toggle ref, also
remove the associated data.
2023-12-28 08:39:41 +01:00
Thomas Haller
4da4220c8b gobject: remove unnecessary "object" field from ToggleRefStack
We always have at hand the object pointer that we care about.
Tracking it also in ToggleRefStack is redundant and unnecessary.

Drop the field.
2023-12-28 08:39:41 +01:00
Emmanuele Bassi
eddd04add1 Merge branch 'ebassi/fix-gir-location-for-docs' into 'main'
build: Tell gi-docgen where to find the GIR files

See merge request GNOME/glib!3792
2023-12-27 16:25:54 +00:00
Emmanuele Bassi
0db7395ef9 build: Tell gi-docgen where to find the GIR files
Now that all files are located under top_srcdir/introspection, we need
to ensure that gi-docgen can find them.
2023-12-27 16:00:06 +00:00
Michael Catanzaro
686ab492cf Merge branch 'g_get_num_processors-affinity-fix' into 'main'
Account for cpu affinity in g_get_num_processors

Closes #1010

See merge request GNOME/glib!3784
2023-12-22 16:11:46 +00:00
Kryggird
09de26185e Account for cpu affinity in g_get_num_processors 2023-12-22 16:11:45 +00:00
Philip Withnall
e597b189c3
2.79.0
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2023-12-22 15:37:24 +00:00
Philip Withnall
994bf21d9d gdatetime: Fix title of documentation comment
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2023-12-22 14:48:30 +00:00
Philip Withnall
ec3fb9a48c Merge branch 'glib-gir-sources' into 'main'
gobject: Make GLib-2.0 gir build depend on GObject dependency

See merge request GNOME/glib!3772
2023-12-22 14:45:37 +00:00
Philip Withnall
b546299fb9 Merge branch '3155-girepository-version' into 'main'
girepository: Re-number GIR file from 2.0 to 3.0

See merge request GNOME/glib!3786
2023-12-22 12:43:06 +00:00
Philip Withnall
a35c6f764d girepository: Re-number GIR file from 2.0 to 3.0
The library shipped by gobject-introspection.git was
`libgirepository-1.0.so`, but for some reason (accident?), it was
accompanied by `GIRepository-2.0.gir`. That’s been the case for the last
6 years.

In moving libgirepository to glib.git, we’ve bumped the version to
`libgirepository-2.0.so`, and have changed the API.

In order to avoid a collision between the new `GIRepository-2.0.gir` and
the old `GIRepository-2.0.gir`, we can either:
 * Rename the basename of the library (confusing).
 * Re-version the whole thing to 3.0 (would mean it’s completely out of
   sync with the rest of glib.git, and would lead to build system
   misery).
 * Re-version only the GIR file (a bit confusing, but hopefully less
   confusing).

So I’ve done the final option: glib.git now ships
`libgirepository-2.0.so` and `GIRepository-3.0.gir`. This avoids
collisions with what’s shipped by gobject-introspection.git, while
hopefully still making some sense.

We considered using version number 2.1 rather than 3.0, but decided
against it because that makes it look like it’s compatible with version
2.0, which it isn’t.

Note that none of these changes touch the
`${prefix}/lib/girepository-1.0` and `${prefix}/share/gir-1.0`
directories. The version numbers in those refer to the versions of the
GIR and typelib file formats, which have not changed.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3155
2023-12-22 12:21:57 +00:00
Philip Withnall
2473268574 Merge branch 'gtypemodule-fix-mem-leaks' into 'main'
gtypemodule: Add assertions in finalize()

See merge request GNOME/glib!3779
2023-12-22 12:15:54 +00:00
Philip Withnall
d55d40a603 Merge branch 'mcatanzaro/#3203' into 'main'
gapplication: ensure app ID is set when sending notification

Closes #3203

See merge request GNOME/glib!3785
2023-12-21 19:50:16 +00:00
Emmanuele Bassi
cda15952dd Merge branch '3037-install-docs' into 'main'
docs: Install the gi-docgen docs

See merge request GNOME/glib!3787
2023-12-21 18:23:53 +00:00
Gaël Bonithon
55e2d9f6a7 gtypemodule: Add assertions in finalize() 2023-12-21 18:25:36 +01:00
Philip Withnall
4c23a17752 Merge branch '3037-man-rst2man' into 'main'
docs: Port the man pages from DocBook to reStructuredText

Closes #3037

See merge request GNOME/glib!3775
2023-12-21 17:04:33 +00:00
Philip Withnall
d2dbfba208 docs: Install the gi-docgen docs
They are now installed to (e.g.)
`${prefix}/share/doc/glib-2.0/{glib,gmodule,gobject,gio}/index.html`.

We might want to drop one level of nesting out of that, but for the
moment I thought I’d keep it in so we can disambiguate by installed
major version.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3037
2023-12-21 17:00:06 +00:00
Michael Catanzaro
c2fab14030 gapplication: ensure app ID is set when sending notification
Otherwise, we hit a bunch of criticals later on. Also, document this
requirement to ensure there is no ambiguity.

Fixes #3203
2023-12-21 10:44:25 -06:00
Philip Withnall
020ebe42f9 build: Change default for -Dman-pages from disabled to auto
Previously, `-Dman=false` was the default, because the generated man
pages were shipped in the distribution tarball already, so the option
actually mostly controlled whether to *re*build them.

The generated pages are no longer shipped in the tarball (and probably
haven’t been since the port to Meson, though I haven’t checked), so it
makes sense to change the default to encourage building the man pages if
the right tooling (`rst2man`) is available.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2023-12-21 16:13:03 +00:00
Marco Trevisan
419777b0f1 Merge branch 'gir-use-gstrv' into 'main'
girepository: Return enumerated versions and search paths as a GStrv

See merge request GNOME/glib!3773
2023-12-21 14:37:07 +00:00
Philip Withnall
031e65808d docs: Port the man pages from DocBook to reStructuredText
So they are consistent with the way we’re building man pages in other
projects, and because some people are allergic to XML.

This changes the build-time dependencies from `xsltproc` to `rst2man`,
and also takes the opportunity to change the `-Dman` Meson option from a
boolean to a feature (so you should use `-Dman-pages={enabled,disabled}`
now, rather than `-Dman={true,false}`).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3037
2023-12-21 13:34:48 +00:00