This changes behavior from commit [1] most similar to what was before.
The point of g_object_run_dispose() is to break reference cycles to
bring down an object. We don't expect the object to take new references
to keep it alive for longer. We probably also don't expect it to
register new weak references. We also don't expect the dispose() callees
to check g_weak_ref_get() for the object. In that case, this change
makes not difference.
Note that during g_object_run_dispose() the ref count does not yet go to
zero, still we clear GWeakRef. As such, GWeakRef rather tracks when
objects get disposed, instead of when the ref count really goes to zero.
That is intentional (e.g. issue [2]).
But compare to g_object_unref(), where we also clear GWeakRef *before*
calling dispose. That makes more sense, because inside dispose() (and
for example during weak notifications), we probably want to see that
g_weak_ref_get() indicates the object is already disposed. For that
reason, it seems more correct to clear out the GWeakRef before calling
dispose().
Also, the dispose() callees (e.g. the weak notifications) might refuse to
let the object die by intentionally keeping strong references around.
Not sure why they would do that, it is similar to resurrecting an object
during dispose(). But if they do, they might also want to register new
GWeakRef. In that case, we wouldn't want to unset those newly set
GWeakRef unconditionally right after.
In most cases, it shouldn't make a difference. In the case where it
does, this is the more sensible order of doing things.
[1] commit 2952cfd7a7 ('gobject: drop clearing quark_weak_locations from g_object_real_dispose()')
[2] https://gitlab.gnome.org/GNOME/glib/-/issues/2266
During object initialization, we may want to freeze the notifications,
but only do so once (and once unfreeze at the end).
Rework how that was done. We can avoid an additional GData lookup.
By now, GObjectNotifyQueue gets reallocated. So quite possibly if we
keep the queue, it is a dangling pointer.
That is error prone, but it's also unnecessary. All we need to know is
whether we bumped the freeze count and need to unfreeze. The queue
itself was not useful, because we anyway must take a lock (via
g_datalist_id_update_atomic()) to do anything with it.
Instead, use a nqueue_is_frozen boolean variable.
GSList is almost in all use cases a bad choice. It's bad for locality
and requires a heap allocation per entry.
Instead, use an array, and grow the buffer exponentially via realloc().
Now, that we use g_datalist_id_update_atomic(), it is also easy to
update the pointer. Hence, the GObjectNotifyQueue struct does not point
to an array of pspecs. Instead the entire GObjectNotifyQueue itself gets
reallocated, thus saving one heap allocation for the separate head
structure.
The members of `struct segment_command` appear to have type `uint32_t`,
so definitely need casting to the machine’s integer pointer type before
doing pointer arithmetic on them.
See https://developer.apple.com/documentation/kernel/segment_command
Tested only on macOS CI as I don’t have access to a macOS machine.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
Because of the generic nature of `GError`, `g_set_error()` has to take
an `int`, but `g_file_error_from_errno()` returns a `GFileError`. The
macOS CI runner decides that’s a good reason to emit
`-Wsign-conversion`.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
This struct is only ever heap allocated, and enums are always the same
size as an int (or unsigned int), so it won’t change size.
The struct doesn’t correspond to any mmapped structure from a
typelib file.
This should fix some `-Wsign-conversion` warnings (curiously only seen
on the macOS CI runner) by using the most specific type.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
Parsing scripts using g_shell_parse_argv() line by line, it's useful to
have empty comments, so one can write pragraphs etc, e.g.
# This is a comment with multiple paragraphs.
#
# It's useful to split things up like this at times.
#
# The empty comment characters makes it clear the paragraphs form a
# single comment.
If g_file_set_contents{_full,} is replacing an existing file, require
that the tmpfile have the same mode as the existing file.
This prevents the umask from taking effect for consistent writes to
existing files.
ClosesGNOME/dconf#76
We can tighten up the types which are being used, to prevent the
warnings. Not everything in the world has to be a `guint`.
These warnings only showed up on the macOS CI runner.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
These only show up on macOS. Apparently it’s more sensitive to assigning
`gboolean` (which is secretly `int`) to a `guint` bitfield. 🤷
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
These don’t show up for me on Linux, but are now causing CI failures on
macOS (https://gitlab.gnome.org/GNOME/glib/-/jobs/5006543):
```
../gobject/gclosure.c:923:40: error: implicit conversion changes signedness: 'gboolean' (aka 'int') to 'guint' (aka 'unsigned int') [-Werror,-Wsign-conversion]
ATOMIC_SET (closure, in_marshal, in_marshal);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
```
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This makes the code a little clearer. In most cases, it’s not a
functional change.
In a few cases, the values are different. I believe the original values
were incorrect (accidentally transposed, perhaps). This never caused an
issue because they were all immediately overwritten during construction
of a `GParamSpec`: these values were defaults in the `instance_init`
vfunc of the `GTypeInstance` for a `GParamSpec`, but the actual min/max
for the `GParamSpec` instance were immediately written over them in the
constructor (such as `g_param_spec_int()`).
Spotted in !4593.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Notably without the (array), the argument of g_byte_array_append appears
as
<type name="guint8" c:type="const guint8*"/>
which will cause the bindings to pass a byte, not a pointer.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
The "without first having or creating a strong reference" part is wrong.
While we invoke the dispose() method, we always still hold the last
reference. The calling thread called g_object_unref() with a strong
reference that we are about to give up, but at the point where we call
dispose(), we didn't yet decrement the ref count to zero. Doing so would
be a fatal bug.
As such, during dispose() the object is still healthy and still has a
strong pointer. You can call `g_weak_ref_set()` on that pointer without
taking an additional strong reference. Of course, if you don't actually
take a strong reference (and thus don't resurrect the object), then
right afterwards, the last reference is dropped to zero, and the
GWeakRef gets reset again.
But there is no need to claim that you need to take another strong
reference to set a GWeakRef during dispose(). This was always the case.
Also, reword the previous paragraph. I think this is clearer.
Otherwise, it appears as an "in" parameter with
<type name="gint" c:type="volatile gint*"/>
which is very confusing to the bindings.
An alternative would be to mark it as an "inout" integer, which matches
the semantics somewhat. However, that wouldn't quite capture the concept
of the value being modified having (pointer) identity, which is of
utmost importance for atomic operations. Hence, just say that we accept
a pointer to the value.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
The array is allocated by the *caller*, not the callee, and then filled
by the callee during the call.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
We don’t want `CONTRIBUTING.md` to become an exhaustive manual of how to
contribute to what is a fairly standard C project using Meson, but it is
a fairly helpful hint to mention how to run the test suite. Then people
can use `meson test --help` and the Meson documentation to learn more.
Pointed out on !4589.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
As with previous commits, we’re enabling `-Wsign-conversion` piecemeal
for all of glib.git.
The previous few commits have fixed all the `-Wsign-conversion` warnings
in libgirepository, so let’s enable the warning by default for that
directory to prevent regressions.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
Due to passing around file lengths variously as `gsize` or `gssize`,
we can’t reliably handle files with length greater than `G_MAXSSIZE`, as
some of the APIs in use need `-1` to indicate that their input is nul
terminated.
Add some checks for this, and gracefully return an error if an input
file is too big, rather than just exploding.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
When parsing a GIR or building a typelib, stop setting the array length
field to `-1` as a default. That field is unsigned, so setting it to
`-1` is actually equivalent to setting it to `G_MAXUINT`. I can’t find
anywhere which treats `G_MAXUINT` or `-1` as a magic value there, so
it’s probably better off left unset.
Given the lack of documentation for the typelib code, though, there is a
fair chance I’m making a mistake and this is actually an integral part
of the format. Let’s see what breaks.
This fixes a `-Wsign-conversion` warning, at least.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
This follows up from the previous two commits to add a unit test.
It doesn’t attempt to cover the multitude of other possible type parsing
conditions; at the moment it’s just a regression test for the previous
two commits, and somewhere to hang new tests on in future.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Reworking the code to add proper `GError` handling for type parsing,
rather than the existing `g_critical()`, turned out to actually be
fairly straightforward.
So now `gi_ir_parser_parse_string()` returns
`G_MARKUP_ERROR_INVALID_CONTENT` on unparseable types, just like it does
with various other bits of invalid GIR.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>