Commit Graph

1826 Commits

Author SHA1 Message Date
Philip Withnall
a9e3e3715a genums: Add missing (transfer) and (nullable) return annotations
This commit only looks at the `Returns:` lines in the documentation, and
has examined all of them in the file. Function arguments have not been
checked.

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

Helps: #2227
2020-12-11 23:48:35 +00:00
Sebastian Dröge
e82eb490fe Handle the case of g_object_run_dispose() in GBinding
When this is called on the source or target, the weak notify of the
corresponding object is called without the GWeakRef being cleared.
See https://gitlab.gnome.org/GNOME/glib/-/issues/2266 for that issue.

This means that a strong reference to these zombie objects can be
retrieved from the GWeakRefs and the previous assumption that this can't
happen was wrong. Remove the assertion for that accordingly and handle
this case.

Specifically, all signal handlers and weak notifies of the object are
already gone and must not be disconnected/removed a second time, or
otherwise memory corruption would be caused. Instead just set the
GWeakRef to NULL and handle it otherwise as if the GWeakRef didn't give
a strong reference to begin with.

Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/2265
2020-12-08 18:41:27 +02:00
Sebastian Dröge
a2de4b2479 Clarify in g_object_weak_ref() docs that the callback is called during disposing and not finalizing
This especially has the effect that any GWeakRefs to the object will not
necessarily be set to NULL yet if called as part of
g_object_run_dispose() and not as part of g_object_unref().
2020-12-08 18:09:50 +02:00
Philip Withnall
5e1d368eec Merge branch 'binding-threadsafe-2' into 'master'
Make GBinding thread-safe (alternative approach)

See merge request GNOME/glib!1745
2020-12-04 14:23:10 +00:00
Sebastian Dröge
52261f0abe Deprecate g_binding_get_source() and get_target() in favour of dup_source() and dup_target()
The old functions are not thread-safe by design.
2020-11-26 19:51:56 +02:00
Sebastian Dröge
7367c5d367 Release GBinding transform functions also when implicitly unbinding because source/target are finalized
This was inconsistently handled before and only explicit unbinding or
finalizing the binding would've previously released the transform
function. If the source/target were finalized while more strong
references to the binding still existed then the transform function
would stay alive and only the binding itself would be deactivated.
2020-11-26 19:51:56 +02:00
Sebastian Dröge
cc15c933b3 Add tests for GBinding thread-safety 2020-11-26 19:51:56 +02:00
Sebastian Dröge
d296ad435d Factor out common GBinding unbind code into a separate function
This was previously duplicated in two places.
2020-11-26 19:30:54 +02:00
Sebastian Dröge
98bbe4f4d1 Make transform function handling in GBinding thread-safe
Unbinding can happen from one thread while a property notification is
being handled concurrently in another one.

To solve this, introduce a reference counter for the transform function
that ensures that it always stays valid while in use and protect access
to the one stored inside the binding with the unbind mutex.
2020-11-26 19:30:48 +02:00
Sebastian Dröge
1daee6ac64 Make explicit/implicit GBinding unbinding thread-safe
It's possible for g_binding_unbind() to be called at the same time as
one (or both) of source and target are being finalized. The resulting
unbinding needs to be protected with a mutex to ensure that it only
happens exactly once.

As the first reference is owned by both weak notifies and the caller of
g_object_bind_property(), additional indirections are needed to ensure that
unreffing the first reference after creation still unbinds the binding
as before. This seems to be a common code pattern and how this was
intended to be used, but is only safe in single-threaded contexts as it
relies on both the source and target object to be still alive.

Add a lot of comments to the code about all these dependencies and a
couple of assertions to ensure they hold valid.

Also document that inconsistent reference ownership handling of
g_binding_unbind() that makes it unfit for automatically generated
language bindings.
2020-11-26 16:15:36 +02:00
Sebastian Dröge
c8c829fa42 Add g_binding_dup_target() and g_binding_dup_source()
These new getters prevent the source/target from simply disappearing if
they're finalized from another thread in the meantime.
2020-11-26 10:49:23 +02:00
Sebastian Dröge
51ee5cf1c2 Use GWeakRef in GBinding
This makes GBinding slightly more thread-safe as the source/target can't
simply disappear.
2020-11-26 10:49:18 +02:00
Philip Withnall
77361ef45e Merge branch 'fix_extra_warnings' into 'master'
Fix more warnings

See merge request GNOME/glib!1765
2020-11-24 15:37:21 +00:00
Emmanuel Fleury
236d6281b8 Fix signedness warnings in gobject/gobject.c:g_object_new_internal()
gobject/gobject.c: In function ‘g_object_new_internal’:
gobject/gobject.c:1962:25: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
 1962 |           for (j = 0; j < n_params; j++)
      |                         ^
gobject/gobject.c:1989:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
 1989 |       for (i = 0; i < n_params; i++)
      |                     ^
2020-11-24 16:17:46 +01:00
Emmanuel Fleury
7753a0492b Fix signedness warnings in gobject/gobject.c:g_object_new_with_custom_constructor()
gobject/gobject.c: In function ‘g_object_new_with_custom_constructor’:
gobject/gobject.c:1836:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
 1836 |       for (j = 0; j < n_params; j++)
      |                     ^
gobject/gobject.c:1914:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
 1914 |   for (i = 0; i < n_params; i++)
      |                 ^
2020-11-24 16:17:46 +01:00
Emmanuel Fleury
d50d2098b5 Fix signedness warning in gobject/gobject.c:g_object_class_install_properties()
gobject/gobject.c: In function ‘g_object_class_install_properties’:
gobject/gobject.c:766:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
  766 |   for (i = 1; i < n_pspecs; i++)
      |                 ^
2020-11-24 16:17:46 +01:00
Emmanuel Fleury
e28d9defb1 Fix signedness warning in gobject/gtype.c:g_type_interface_add_prerequisite()
gobject/gtype.c: In function ‘g_type_interface_add_prerequisite’:
gobject/gtype.c:1607:21: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
 1607 |       for (i = 0; i < prerequisite_node->n_supers + 1; i++)
      |                     ^
2020-11-24 16:17:37 +01:00
Michael Catanzaro
fb6e10c959 gtype: suppress valgrind memory leak warnings
The problem occurs because we keep a pointer inside the allocated block,
instead of a pointer to the start of the block. This memory exists for
the lifetime of the application, so let's silence it.

This is probably abuse of VALGRIND_MALLOCLIKE_BLOCK(), which is really
intended for use in memory allocators, but gtype.c already uses it in
two other places, and it's a practical solution. I wrote another larger
fix for this issue that involves keeping an array of extra pointers when
running under valgrind. This is simpler.

Fix suggested by Philip Withnall

```
==180238== 16 bytes in 1 blocks are possibly lost in loss record 3,078 of 16,075
==180238==    at 0x483BB1A: calloc (vg_replace_malloc.c:762)
==180238==    by 0x5489495: g_malloc0 (gmem.c:132)
==180238==    by 0x5489754: g_malloc0_n (gmem.c:364)
==180238==    by 0x53FDBEE: type_set_qdata_W (gtype.c:3722)
==180238==    by 0x53FDEE8: type_add_flags_W (gtype.c:3787)
==180238==    by 0x53FC348: g_type_register_fundamental (gtype.c:2662)
==180238==    by 0x53D969B: _g_enum_types_init (genums.c:124)
==180238==    by 0x53FF058: gobject_init (gtype.c:4432)
==180238==    by 0x53FF082: gobject_init_ctor (gtype.c:4493)
==180238==    by 0x4010F29: call_init.part.0 (dl-init.c:72)
==180238==    by 0x4011030: call_init (dl-init.c:30)
==180238==    by 0x4011030: _dl_init (dl-init.c:119)
==180238==    by 0x4002149: ??? (in /usr/lib64/ld-2.30.so)
```

Fixes #2076
2020-11-24 08:10:58 -06:00
Michael Catanzaro
a412ffe4d3 gatomicarray: suppress valgrind memory leak warnings
The problem occurs because we keep a pointer inside the allocated block,
instead of a pointer to the start of the block:

```
==180238== 16 bytes in 1 blocks are possibly lost in loss record 3,086 of 16,075
==180238==    at 0x483980B: malloc (vg_replace_malloc.c:309)
==180238==    by 0x548942C: g_malloc (gmem.c:102)
==180238==    by 0x54A4748: g_slice_alloc (gslice.c:1025)
==180238==    by 0x53D0AAF: freelist_alloc (gatomicarray.c:77)
==180238==    by 0x53D0B85: _g_atomic_array_copy (gatomicarray.c:133)
==180238==    by 0x53F8E6D: iface_node_set_offset_L (gtype.c:1347)
==180238==    by 0x53F91F1: type_node_add_iface_entry_W (gtype.c:1444)
==180238==    by 0x53F93DF: type_add_interface_Wm (gtype.c:1477)
==180238==    by 0x53FC946: g_type_add_interface_static (gtype.c:2852)
==180238==    by 0x4A3D53A: gtk_menu_shell_accessible_get_type_once (gtkmenushellaccessible.c:26)
==180238==    by 0x4A3D495: gtk_menu_shell_accessible_get_type (gtkmenushellaccessible.c:26)
==180238==    by 0x4C8AC44: gtk_menu_shell_class_init (gtkmenushell.c:424)
```

Note we cannot use VALGRIND_FREELIKE_BLOCK() in freelist_free() because we
have not actually freed the FreeListNode and need to dereference it in
freelist_alloc() to decide whether to reuse the block. That would result
in a use-after-free warning before we would get a chance to call
VALGRIND_MALLOCLIKE_BLOCK() in the reuse path.

Also note that this free list only ever grows: it never shrinks for the
lifetime of the application, so nothing here will ever be truely freed,
although unused elements are eligible for reuse.

Fix suggested by Philip Withnall

Related: #2076
2020-11-24 08:10:58 -06:00
Emmanuel Fleury
6b0552bb89 Fix signedness warning in gobject/gtype.c:type_node_add_iface_entry_W()
gobject/gtype.c: In function ‘type_node_add_iface_entry_W’:
gobject/gtype.c:1379:21: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’
 1379 |       for (i = 0; i < num_entries; i++)
      |                     ^
2020-11-22 17:10:53 +01:00
Emmanuel Fleury
f6e234fdb6 Fix signedness warning in gobject/gtype.c:lookup_iface_entry_I()
gobject/gtype.c: In function ‘lookup_iface_entry_I’:
gobject/gtype.c:599:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
  599 |       if (index < IFACE_ENTRIES_N_ENTRIES (entries))
      |                 ^
gobject/gatomicarray.h:51:8: note: in definition of macro ‘G_ATOMIC_ARRAY_DO_TRANSACTION’
   51 |       {_C_;}         \
      |        ^~~
2020-11-22 17:10:53 +01:00
Philip Withnall
9f041c9e05 Merge branch 'th/gobject-new-parameter-list' into 'master'
gobject: allocate parameter list for g_object_new_valist() entirely on stack

See merge request GNOME/glib!1385
2020-11-21 22:55:55 +00:00
Sebastian Dröge
fa8a39c6c6 Merge branch 'py-fixes' into 'master'
Python formatting improvements

See merge request GNOME/glib!1757
2020-11-20 18:10:40 +00:00
Philip Withnall
47da8ec5d9 gtype: Add some missing atomic accesses to init_state
Half of the references to `init_state` in `gtype.c` already correctly
accessed it atomically, but a couple didn’t. Drop the `volatile`
qualifier from its declaration, as that’s not necessary for atomic
access.

Note that this is the `init_state` in `TypeData`, *not* the `init_state`
in `IFaceEntry`.

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

Helps: #600
2020-11-20 14:41:07 +00:00
Philip Withnall
041dd8b70b gtype: Fix some typos in comments
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-11-20 14:41:07 +00:00
Philip Withnall
8a112c3c6e tests: Drop unnecessary volatile qualifiers from tests
These variables were already (correctly) accessed atomically. The
`volatile` qualifier doesn’t help with that.

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

Helps: #600
2020-11-20 14:40:19 +00:00
Philip Withnall
334f695336 gobject: Drop volatile qualifier from GObject.ref_count
This is an API break, but no third party code should be touching
`GObject.ref_count`, let alone in a way which would be changed by the
removal of the `volatile` qualifier.

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

Helps: #600
2020-11-20 14:40:19 +00:00
Philip Withnall
46bae4f18d gatomicarray: Drop volatile qualifier from GAtomicArray API
This is an API break, but it should not affect third party code since
that code should not be interacting with the `data` member in a way that
invokes its `volatile` qualifier (such as copying to an intermediate
variable).

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

Helps: #600
2020-11-20 14:40:19 +00:00
Philip Withnall
08d04d0428 gobject: Drop unnecessary volatile qualifiers from internal variables
These variables were already (correctly) accessed atomically. The
`volatile` qualifier doesn’t help with that.

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

Helps: #600
2020-11-20 14:40:19 +00:00
Philip Withnall
fab561f8d0 gobject: Drop use of volatile from get_type() macros
http://isvolatileusefulwiththreads.in/c/

It’s possible that the variables here are only marked as volatile
because they’re arguments to `g_once_*()`. Those arguments will be
modified in a subsequent commit.

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

Helps: #600
2020-11-20 14:40:19 +00:00
Thomas Haller
fb3977e9b4 gobject: limit required stack by heap allocating parameter list in g_object_new_valist()
The previous code consumed a larger additional amount of stack space.
That is because it would allocate the temporary buffer for GValues on
the stack with "g_newa (GValue, 1)" and thus the required stack
space grew with the number of arguments. Granted, this is already
a variadic C function, so the caller already placed that many elements
on the stack. For example, on the stack there are the property names
and the pointers to the arguments, which should amount to roughly
O(n_args * 16) (on 64 bit, with pointers being 8 bytes large).

That is not bad, because it means in the previous version the stack space
would grow linear with the already used stack space. However, a GValue is
an additional 24 bytes (on 64 bit), which probably more than doubles the
required stack space. Let's avoid that, by allocating the temporary list
on the heap after a certain threshold. This probably more than doubles the
number of possible arguments before the stack overflows.

Also, previously the heap allocated "params" array only grew one element
per iteration. Of course, it is likely that libc anyway reallocates
the buffers by growing the space exponentially. So realloc(ptr, 1)
probably does not O() scale worse than doubling the buffer sizes ourselves.
However, it seems clearer to keep track of the allocated sizes ourself, and
only call realloc() when we determine that we are out of space.
Especially because we need to update the value pointers on reallocation.

Note that we now require a heap allocation both for the "params" and the
"values" list. Theoretically that could be combined by using one buffer
for both. But that would make the code more complicated.

Now we pre-allocate buffers for 16 elements on the stack. That
is (16 * (16 + 24) bytes (or 640 bytes) on the stack. I think that
is still acceptable.
2020-11-18 15:26:14 +01:00
Thomas Haller
355c99a077 object: use guint type for n_params argument of g_object_new_is_valid_property()
Two out of three callers pass the count argument from a variable
of type guint. And the third is currently an always positive gint.

We should use the correct integer type that matches the type as it
used otherwise.
2020-11-18 13:38:53 +01:00
Philip Withnall
d270b6c3db py: Various flake8 cleanups
None of these are particularly significant, but they do get the CI
output clean.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-11-17 15:50:07 +00:00
Philip Withnall
905b22a17e py: Reformat all Python files consistently
This commit is the unmodified results of running
```
black $(git ls-files '*.py')
```
with black version 19.10b0. See #2046.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-11-17 15:50:07 +00:00
Philip Withnall
a65fe37e5c gobject: Clarify documentation and annotations of g_set_object()
Heavily based on changes suggested by Дилян Палаузов.

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

Fixes: #1849
2020-11-14 20:35:09 +00:00
Sebastian Dröge
ddef9ba2f8 Merge branch 'instantiatable' into 'master'
gobject: Standardise on the term ‘instantiatable’

See merge request GNOME/glib!1735
2020-11-13 15:29:07 +00:00
Matthias Clasen
0b1f909691 Add a test for signals returning interface types
Add a test for a signal returning interface types, using
the generic marshaller. This will hopefully exercise newly
added code in value_from_ffi_type().
2020-11-02 17:36:18 +00:00
Matthias Clasen
52357aac44 Add a binding test involving interfaces
This tests the new functionality that
g_type_interface_instantiable_prerequisite
was added for.

Before the changes, this fails with
GObject-WARNING **: Unable to convert a value of type \
                    GObject to a value of type Foo

We do the same test with g_object_bind_property_with_closures
as well, to exercise g_cclosure_marshal_generic.
2020-11-02 17:36:18 +00:00
Benjamin Otte
458e3b7a84 value: Allow automatic transforms to/from interfaces
Use the new g_type_interface_instantiable_prerequisite() to check
compatibility for transform functions.

In particular, this allows interfaces (in my case GDK_TYPE_PAINTABLE) to
be transformed to/from any GObject type (in my case G_TYPE_OBJECT) using
the transform function registered to transform between any 2 objects
(g_value_object_transform_value() does a type check and uses NULL if the
types don't match).

And this in turn allows be to g_object_bind_property() a gobject-typed
generic property (GtkListItem::item) to a GtkImage::paintable.

Tests for the new functionality are included.
2020-11-02 17:36:18 +00:00
Benjamin Otte
3f2a8d53f0 closure: Support generic marshals for interface returns
Use the newly added g_type_interface_instantiable_prerequisite() to
allow closure return values being interfaces by looking up the
instantiable type for the interface and using its GValue accessors.
2020-11-02 17:36:18 +00:00
Benjamin Otte
98f0a5a7da gtype: Add g_type_interface_instantiatable_prerequisite()
This function returns the most specific instantiatable type
that is a prerequisite for a given interface.

This type is necessary in particular when dealing with GValues
because a GValue contains an instance of a type.

This commit includes tests for the new API.
2020-11-02 17:36:18 +00:00
Benjamin Otte
e1b5afb7c0 gtype: Fix typo in API comment 2020-11-02 17:36:18 +00:00
Benjamin Otte
1f6c73747e Suggest braces around empty body in ‘if’ statements 2020-11-02 17:36:18 +00:00
Philip Withnall
4f2b1e250d gobject: Standardise on the term ‘instantiatable’
Rather than using a mixture of ‘instantiable’ and ‘instantiatable’
everywhere, standardise on the term which is already in the public API.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-11-02 17:22:01 +00:00
Sebastian Dröge
c686e1a048 Add various missing nullable annotations 2020-10-19 13:28:46 +03:00
Philip Withnall
e2e8339e0a Merge branch 'typeof' into 'master'
Use C++11 decltype where possible

See merge request GNOME/glib!1575
2020-10-15 08:52:47 +00:00
Xavier Claessens
5b2bee3f53 Replace __typeof__ with glib_typeof macro
g_has_typeof macro is wrongly in the public g_ namespace, internaly
symbols are usually in the glib_ namespace. This will also allow to
define glib_typeof differently on non-GNUC compilers (e.g. c++11
decltype).
2020-10-14 14:48:36 -04:00
Ray Strode
d691c2ebd2 gsignal: Plug g_signal_connect_object leak
commit 916297be79 added a hash table
to provide constant time lookups of signal handlers.

Unfortunately, that commit neglected to remove handlers from
g_signal_connect_object calls from the hash table that are
disconnected implicitly when the associated object goes away.

This commit addresses that bug by changing the closure invalidate
handler associated with the signal connection to properly remove the
handler from the hash table.
2020-10-13 09:49:29 -04:00
Andrew Potter
3dc62171eb Add boxing for GTree
Closes issue #1233
2020-10-07 11:00:11 +01:00
Philip Withnall
648986a290 glib: Avoid redefining GLIB_DISABLE_DEPRECATION_WARNINGS
It may be defined by the environment (we document that as being allowed)
— if so, individual files should not try to redefine it, as that causes
a preprocessor warning.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
2020-07-27 15:41:09 +01:00