We used to store the search paths into a GSList but this is not
efficient for various reasons, so replace this with an array so that we
can replace return just a GStrv in the public API.
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.
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