Previously:
- if the object is currently not frozen, we called
g_object_notify_queue_freeze() once. Afterwards dispatch the event
directly. This is probably the common case, and requires one
notify_lock lock.
- if the object is currently frozen, we call
g_object_notify_queue_freeze(), g_object_notify_queue_add().
g_object_notify_queue_thaw().
This required taking the notify_lock three times.
- if the object is currently not frozen and in_init, then we called
g_object_notify_queue_freeze(), g_object_notify_queue_freeze(),
g_object_notify_queue_add(). This also required to take
the lock three times. There is another thaw at the end of
object initialization.
That was because we first call g_object_notify_queue_freeze() to see
whether we are frozen. And depending on that, queue the event (and thaw
again).
Instead, g_object_notify_queue_add() can do the check and queueing in
one step. There is no need to call a freeze() to (conditionally) enqueue
a notification. Now only one lock is taken in all cases.
Also, g_object_notify_queue_freeze() and g_object_notify_queue_thaw()
both call g_datalist_id_get_data() (which also take a bit lock). As the
thaw is no longer necessary, the second lock is also saved.
Before dispatching signals (and calling out to user code), we want to
take a reference and ensure that the object stays alive.
However, a thaw may not decrease the freeze_count to zero, or there may
be no properties to notify. Avoid taking a reference in those cases.
This was done since the beginning (commit e773d7dba6 ('fixed dealing
with collection/lcopy of NULL values.'). But it's not clear, why we
would need to take a reference on the calling object.
Freeze does not emit any signals/callbacks and does not call back to the
user. It just sets up some internal state.
This doesn't require to take a reference. The caller must hold a valid
reference to being with, but if that's given, there is no need to
acquire another reference.
g_atomic_int_get() returns a signed int. While we don't expect this to be ever
negative, a negative value would also indicate a bug. Adjust the check to assert
against negative ref-count too.
Without this when compiling GLib with address sanitizer enabled, we'd
end up failing with this error:
==375535==ASan runtime does not come first in initial library list;
you should either link runtime to your application or manually preload
it with LD_PRELOAD.
Now, given that addressing the fix implies doing more radical changes,
it's just fine here to ignore ASAN to work on tools we use for building
gir files.
Generating gir and typelib files has inter-dependencies that may depend
on other elements.
For example, glib requires gobject and gdump generated files require
gmodule, so we've a cyclic dependency because gmodule requires gobject,
that requires glib.
To prevent this, let's just generate the introspection files at once in
a different meson file so that we don't have to deal with this.
As per this we could even revert commit fa37ab6d0 since gio is now
compiled before the gir files.
GLib gir requires glib-types.h that also includes gobject-visibility.h
that needs to be generated in order to be able to generate the GLib gir,
so explicitly add it to the sources.
Also, in order to link the typelib we need the definitions of the *_get_type()
functions that are defined in the gboxed.c file, so this should be part
of the gir sources or we'll have linking issues.
The code for stripping the query and fragment from file:// URIs was
wrong, as it would not properly strip a query if there was a fragment.
Fortunately, that code was actually useless, as the "stripped URI" was
passed to g_filename_from_uri() that does proper stripping itself.
So simply drop this extra unnecessary stripping logic from GLocalVFS's
get_file_for_uri() and let g_filename_from_uri() do all the work.
Aside from checking that we're accessing the global GParamSpecPool
without necessarily initializing GObjectClass, we should also verify
that we're doing so safely without the class init lock.
Ensure that the fix in commit af024b6d7e7d3fbef23c1f7d1f7704fc90ac4fb1
works, by replicating what gobject-introspection does:
- initialise the default GTypeInterface from a GType without also
initialising GObjectClass
- install a property for the interface
- find the GParamSpec using g_object_interface_find_property()
Right now, we're assuming that GObjectClass will be initialised first
and under a lock, but that's not always the case: when traversing a list
of type, the first one might be a GTypeInterface, and if we initialise
an interface that installs a property, the whole thing comes crashing
down because the global GParamSpecPool is not initialised.
Instead of taking a lock everywhere, we can use an atomic compare and
swap; the first thread that installs a property wins the race, as any
other access to the GParamSpecPool is performed under a lock.
While GParamSpecPool should never be used by newly written code, having
the ability to free the associated memory is a good idea. The only
reason why this hasn't been necessary until now is that we assume base
classes are going to keep their GParamSpecPool around forever.
It’s not particularly necessary, and makes the build-time dependencies
more complex than they need to be, as it means that to generate
GLib-2.0.gir and GObject-2.0.gir, libgio.so (and its generated headers)
already needs to have been built.
See discussion on https://gitlab.gnome.org/GNOME/glib/-/issues/3164
These changes need to be replicated in gobject-introspection.git before
the problem can be solved, though, as that still has its own copy of
`gdump.c` (which it installs and uses).
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3164
Not that this job is particularly maintained at the moment, but at least
try to keep it up to date.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
Since it now has to build the docs (and code coverage) for `main`, that
needs to happen after branches are merged.
Other jobs remain not-run on merges.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
The actual deployment will be done by
https://gitlab.gnome.org/GNOME/gtk/-/blob/docs-gtk-org/; it pulls the
most recent artifact zip from glib.git.
This ensures that only one project/job/branch has push access to the
website.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
The same struct was reused across multiple tests, but without a shared
way of freeing its members. Refactor to add one.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The current buffer API is pretty much C-specific, and cannot be
adequately described in a way that is friendly to introspection and
language bindings: the passed buffer is allocated by the caller, but the
written size of the buffer is in the return value.
Using GBytes, we get a better API at the cost of an additional
allocation.
If more documentation needs to be added, it either needs to be added as
docblock comments next to the relevant symbols, or as additional
Markdown files. Not in a random C file.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3155