This won’t really affect anything, but we might as well fix them to not
crash if called with an empty `argv` by someone (ab)using `execve()`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Much like GBindingGroup, the GSignalGroup object allows you to connect many
signal connections for an object and connect/disconnect/block/unblock them
as a group.
This is useful when using many connections on an object to ensure that they
are properly removed when changing state or disposing a third-party
object.
This has been used for years in various GNOME projects and makes sense to
have upstream instead of multiple copies.
Originally, GBindingGroup started with Builder as a way to simplify all
of the third-degree object bindings necessary around Model-Controller
objects such as TextBuffer/TextView.
Over time, it has grown to be useful in a number of scenarios outside
of Builder and has been copied into a number of projects such as GNOME
Text Editor, GtkSourceView, libdazzle, and more.
It makes sense at this point to unify on a single implementation and
include that upstream in GObject directly alongside GBinding.
Glib cannot be built statically on Windows because glib, gobject and gio
modules need to perform specific initialization when DLL are loaded and
cleanup when unloaded. Those initializations and cleanups are performed
using the DllMain function which is not called with static builds.
Issue is known for a while and solutions were already proposed but never
merged (see: https://gitlab.gnome.org/GNOME/glib/-/issues/692). Last
patch is from version 2.36.x and since then the
"constructor/destructor" mechanism has been implemented and used in
other part of the system.
This patch takes back the old idea and updates it to the last version of
glib to allow static compilation on Windows.
WARNING: because DllMain doesn't exist anymore in static compilation
mode, there is no easy way of knowing when a Windows thread finishes.
This patch implements a workaround for glib threads created by calling
g_thread_new(), so all glib threads created through glib API will behave
exactly the same way in static and dynamic compilation modes.
Unfortunately, Windows threads created by using CreateThread() or
_beginthread/ex() will not work with glib TLS functions. If users need
absolutely to use a thread NOT created with glib API under Windows and
in static compilation mode, they should not use glib functions within
their thread or they may encounter memory leaks when the thread finishes.
This should not be an issue as users should use exclusively the glib API
to manipulate threads in order to be cross-platform compatible and this
would be very unlikely and cumbersome that they may mix up Windows native
threads API with glib one.
Closes#692
Notifying during object destruction is a dubious "feature": objects
might end up recreating a bunch of state just before clearing it;
language bindings might get spurious notifications during garbage
collection runs.
We freeze the notification queue before running the dispose() chain; if
the object was temporarily vivified during dispose, we thaw the
notification queue, otherwise we let the instance clear it when we
finalize it.
See: https://gitlab.gnome.org/GNOME/gjs/-/issues/445
We now guarantee that GObjects will always be allocated at least as
aligned as the basic types. If you want to put an element in your
GObject which has higher alignment requirements, we can’t guarantee it
will be aligned*. If you need it to be aligned, you’ll need to put it on
the heap (aligned appropriately), or add appropriate padding in your
GObject struct.
*Actually, GSlice will guarantee that the whole GObject is aligned to at
least the power of 2 greater than or equal to the size of the GObject,
which means any element in the GObject struct should always be
appropriate aligned if the compiler pads it appropriately. If malloc()
is used, however, it doesn’t make that guarantee, so we can’t make that
guarantee overall.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1231
Regardless of the actual alignment of the GTypeInstance in question,
these do a runtime check on the type, so if the type was originally
aligned correctly when allocated, it should be aligned correctly if the
type check succeeds. -Wcast-align is meant to warn about casts between
types, which this isn’t (if the check succeeds).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1231
See the reasoning in the patch for why we believe GObjects *are*
(already) as aligned as the basic types.
We want to make this guarantee so that it’s guaranteed to be safe for
people to ignore -Wcast-align warnings for GObjects which contain basic
types. This typically happens with gdouble on 32-bit ARM platforms.
The checks are slightly complicated by the need to support GObjects with
custom constructors. We should expect that a custom construction
function will chain up to g_object_constructor (which calls
g_type_create_instance() as normal), but it’s possible that someone has
done something crazy and uses a custom allocator which doesn’t return
with the same alignment as GSlice. Hand them a warning in that case. If
that is true, the code which uses their custom-constructed GObject can
presumably already deal with the alignment it gets given.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1231
This should remove some warnings from the CI, making it easier to see
legitimate CI failures.
For example, see https://gitlab.gnome.org/GNOME/glib/-/jobs/1621041.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
When an object with toggle reference is notifying a change we just
assume that this is true because of previous checks.
However, while locking, another thread may have removed the toggle
reference causing the waiting thread to abort (as no handler is set at
that point).
To avoid this, once we've got the toggle references mutex lock, check
again if the object has toggle reference, and if it's not the case
anymore just ignore the request.
Add a test that triggers this, it's not 100% happening because this is
of course timing related, but this is very close to the truth.
Fixes: #2394
The previous wording was not clear about what happens if a new weak ref
is taken during disposal (shortly after resurrecting the object with a
new strong ref, otherwise taking the weak ref is invalid).
See: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2064/diffs#note_1270092
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2390
No need to call memset in the loop, we can just
initialize all the values in one go.
GtkBuilder is now using g_object_setv, so this
may improve application start times a bit.
As per the previous change, an object that had weak locations set may
need to lock again the weak locations mutex during qdata cleanup, but
we can avoid this when we know we're removing the last location, by
removing the qdata entry and freeing the data.
In case a new location is needed for the same object, new data will be
added.
However, by doing this the weak locations during dispose may be
invalidated once the weak locations lock is passed, so check again if
this is the case while removing them.
It can happen that a GWeakRef is added to an object while it's disposing
(or even during finalizing) and this may happen in a thread that (weak)
references an object while the disposal isn't completed yet or when
using toggle references and switching to GWeakRef on notification (as
the API suggests).
In such scenario the weak locations are not cleaned up when the object
is finalized, and will point to a free'd area.
So, during finalization and when we're sure that the object will be
destroyed for sure, check again if there are new weak locations and
unset them if any as part of the qdata destruction.
Do this adding a new utility function so that we can avoid duplicating
code to free the weak locations.
Added various tests simulating this case.
Fixes: #2390
The documentation sort of already said this, but it’s better to make it
explicit.
This avoids the situation where some of the weak notify callbacks for an
object have been called, and then a subsequent one resurrects the
object. Without some way of undoing the weak notifications already sent,
that would leave external state which is coupled to the object’s
lifecycle out of sync.
This arose from discussion on !2064.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
GTK currently checks if a GtkWidget is finalized while still using a
floating reference—i.e. a widget was disposed without any parent
container owning it.
This warning can be useful to identify and trace ownership transfer
issues in libraries using initially unowned floating object types.
To avoid introducing constraints ex post, we can gate this check behind
both the G_ENABLE_DEBUG compile time flag for GLib, and behind the
G_ENABLE_DIAGNOSTIC environment variable run time check.
Fixes: #2489
When rendering the contents of the GLib documentation stored inside the
introspection data, a common behaviour is to take the first paragraph as
a summary of the symbol being documented.
The documentation is assumed to be in Markdown format, which means:
- paragraphs must be separated by newlines
- lines that have an indentation of four or more spaces are considered
code blocks
- lines that start with a `#` are considered titles
This means we need to slightly tweak the documentation in our sources to
ensure that it can be rendered appropriately by tools that are not
gtk-doc.
See issue: #2365