The automatic memory management of GBinding is not optimal for high
order languages with garbage collectors semantics. If we leave the
binding instance inert but still referenced it will be leaked, so one
solution that does not throw away the baby of C convenience with the
bathwater of language bindability is to have unbind() perform an
implicit unref().
Hopefully, C developers will read the documentation and especially the
note that says that after calling unbind() the reference count on the
GBinding instance is decreased.
https://bugzilla.gnome.org/show_bug.cgi?id=698018
We have turned up enough cases of this being done (including GTK API
allowing apps to do this to GtkSettings well after it has been
instantiated) that it is clear that we cannot really break this feature
while claiming to be backwards compatible.
For that reason, it becomes a warning rather than a critical (ie: it is
still well-defined behaviour, but you are discouraged from doing it).
The intention is to keep this feature for at least the next while.
A given GObjectClass will be able to avoid using GParamSpec pool for as
long as you don't install properties after init. If you do that, you
will get a warning and we will devolve to using GParamSpecPool.
https://bugzilla.gnome.org/show_bug.cgi?id=698614
Perform a substantial cleanup of the build system with respect to
building and installing testcases.
First, Makefile.decl has been renamed glib.mk and substantially
expanded. We intend to add more stuff here in the future, like canned
rules for mkenums, marshallers, resources, etc.
By default, tests are no longer compiled as part of 'make'. They will
be built when 'make check' is run. The old behaviour can be obtained
with --enable-always-build-tests.
--disable-modular-tests is gone (because tests are no longer built by
default). There is no longer any way to cause 'make check' to be a
no-op, but that's not very useful anyway.
A new glibtests.m4 file is introduced. Along with glib.mk, this
provides for consistent handling of --enable-installed-tests and
--enable-always-build-tests (mentioned above).
Port our various test-installing Makefiles to the new framework.
This patch substantially improves the situation in the toplevel tests/
directory. Things are now somewhat under control there. There were
some tests being built that weren't even being run and we run those now.
The long-running GObject performance tests in this directory have been
removed from 'make check' because they take too long.
As an experiment, 'make check' now runs the testcases on win32 builds,
by default. We can't run them under gtester (since it uses a pipe to
communicate with the subprocess) so just toss them in TESTS. Most of
them are passing on win32.
Things are not quite done here, but this patch is already a substantial
improvement. More to come.
GObject has previously allowed installing properties after class_init
has finished running. This means that you could install some of your
own properties on G_TYPE_OBJECT, for example, although they wouldn't
have worked properly.
A previous patch asserted that this was not true and we had to revert it
because it broke the shell. Instead of reverting, we should have used a
critical, so do that now.
Complaints go to this bug:
https://bugzilla.gnome.org/show_bug.cgi?id=698614
We previously hold a lock in the loop that collects the arguments for
g_signal_emit(), which we drop before calling into the argument
collection functions and reacquire again at the bottom of the loop (ie:
one release/acquire pair for each argument collected). To make matters
worse, the lock is just released again after the loop.
Presumably that was done to protect the access to the parameter array,
but it's pretty unlikely that this is needed because the only way it
changes is if the signal is unloaded. That only happens when unloading
types which is quite unlikely to happen while we are emitting on an
instance of that type (and, as an aside, never happens anymore anyway).
If we move the unlock below the loop up above it and remove the
acquire/release pair from the loop, we improve performance in the new
arg-collecting performance tests by ~15% (more like ~18% in the case
where we only emit to one handler -- where argument collection dominates
more).
https://bugzilla.gnome.org/show_bug.cgi?id=694380
Back in the far-off twentieth century, it was normal on unix
workstations for U+0060 GRAVE ACCENT to be drawn as "‛" and for U+0027
APOSTROPHE to be drawn as "’". This led to the convention of using
them as poor-man's ‛smart quotes’ in ASCII-only text.
However, "'" is now universally drawn as a vertical line, and "`" at a
45-degree angle, making them an `odd couple' when used together.
Unfortunately, there are lots of very old strings in glib, and also
lots of new strings in which people have kept up the old tradition,
perhaps entirely unaware that it used to not look stupid.
Fix this by just using 'dumb quotes' everywhere.
https://bugzilla.gnome.org/show_bug.cgi?id=700746
Higher order languages with garbage collection can have issues releasing
a binding, as they do not control the last reference being dropped on
the binding, source, or target instances.
https://bugzilla.gnome.org/show_bug.cgi?id=698018
There is some code in the wild (like in gnome-session) that does this
from its custom _constructor() implementation:
{
GObject *obj;
obj = ((chain up));
if (!object_is_viable (obj))
{
g_object_unref (obj);
return NULL;
}
else
return obj;
}
This has never been a valid use of GObject and this code has always
caused memory to be leaked[1] by growing the construction_objects list.
The ability to legitimately return NULL from a constructor was exactly
the reason that we created GInitable, in fact.
That doesn't change the fact that the g_object_new() rewrite will crash
in this case, so instead of doing that, let's emit a critical and avoid
the crash. This will allow people to upgrade their GLib without also
upgrading their gnome-session. Meanwhile, people can fix their broken
code.
[1] not in the strictest sense of the word, because it's still reachable
Make a number of improvements to g_object_new():
- instead of looking up the GParamSpec for the named property once in
g_object_new() (in order to collect) and then again in g_object_newv
(when actually setting the property), g_object_new_internal() is a
new function that takes the GParamSpec on the interface to avoid the
second lookup
- in the case that ->constructor() is not set, we need not waste time
creating an array of GObjectConstructParam to pass in. Just directly
iterate the list of parameters, calling set_property() on each.
- instead of playing with linked lists to keep track of the construct
properties, realise that the number of construct properties that we
will set is exactly equal to the length of the construct_properties
list on GObjectClass and the only thing that may change is where the
value comes from (in the case that it was passed in)
This assumption was already implicit in the existing code and can be
seen from the sizing of the array used to hold the construct
properties, but it wasn't taken advantage of to make things simpler.
- instead of allocating and filling a separate array of the
non-construct properties just re-iterate the passed-in list and set
all properties that were not marked G_PARAM_CONSTRUCT (since the ones
that were construct params were already used during construction)
- use the new g_param_spec_get_default_value() API instead of
allocating and setting the GValue for each construct property that
wasn't passed from the user
Because we are now iterating the linked list of properties in-order we
need to append to that list during class initialising instead of
prepending.
These changes show a very small improvement on the simple-construction
performance testcase (probably just noise) and they improve the
complex-construction case by ~30%.
Thanks to Alex Larsson for reviews and fixes.
https://bugzilla.gnome.org/show_bug.cgi?id=698056
The way of getting the default value out of a GParamSpec is to allocate
a GValue, initialise it, then call g_param_spec_set_default() to set the
default value into that GValue.
This is exactly how we handle setting the default value for all of the
construct properties that were not explicitly passed to g_object_new().
Instead of doing the alloc/init/store on all construct properties on
every call to g_object_new(), we can cache those GValues in the private
data of the GParamSpec itself and reuse them.
This patch does not actually make that change to g_object_new() yet, but
it adds the API to GParamSpec so that a future patch to GObject can make
the change.
https://bugzilla.gnome.org/show_bug.cgi?id=698056
Since instance private data is now always at a constant offset to the
instance pointer, we can add an accessor for it that doesn't also
require an instance.
The idea is that classes can call this from their class_init and store
it in a file-scoped static variable and use that to find their private
data on instances very quickly, without a priv pointer.
https://bugzilla.gnome.org/show_bug.cgi?id=698056
This reverts commit ddb0ce1421.
Colin's smoke testing has found issues in at least gjs and
gnome-settings-daemon. We'll need to see if we can address those.
GObject has previously allowed installing properties after class_init
has finished running. This means that you could install some of your
own properties on G_TYPE_OBJECT, for example, although they wouldn't
have worked properly.
Prevent this from happening. Require that all properties are installed by
the time class_init has finished.
Complaints go to this bug:
https://bugzilla.gnome.org/show_bug.cgi?id=698614
Classically, a GTypeInstance has had the following layout:
[[[[GTypeInstance] GObject] TypeA] TypeB] [TypeAPrivate] [TypeBPrivate]
where TypeB is a subclass of TypeA which is a GObject. Both TypeA and
TypeB use pivate data.
The main problem with this approach is that the offset between a pointer
to an instance of TypeA and the TypeAPrivate is not constant: it changes
depending on the depth of derivation and the size of the instance
structures of the derived types. For example, changing the size of the
TypeB structure in the above example would push the TypeAPrivate further
along.
This complicates the implementation of g_type_instance_get_private().
In particular, during object construction when the class pointer to the
'complete type' of the object is not yet stored in the header of the
GTypeInstance, we need a lookup table in order to be able to implement
g_type_instance_get_private() accurately.
We can avoid this problem by storing the private data before the
structures, in reverse order, like so:
[TypeBPrivate] [TypeAPrivate] [[[[GTypeInstance] GObject] TypeA] TypeB]
Now the distance between TypeA and TypeAPrivate depends only on the size
of GObject and GTypeInstance, which are static. Even in the case of
TypeB, the distance is not statically known but can be determined at
runtime and is constant (because we will know the size of TypeAPrivate
by the time we initialise TypeB and it won't change).
This approach requires a slighty dirty trick: allocating extra memory
_before_ the pointer we return from g_type_create_instance(). The main
problem with this is that it will cause valgrind to behave very badly,
reporting almost everything as "possibly lost".
We can correct for this by including a few valgrind client requests in
order to inform it that the start of the GTypeInstance should be
considered a block of memory and that pointers to it should mean that
this block is reachable. In order to make the private data reachable,
we also declare it as a block and include an extra pointer from the end
of the primary block pointing back at it. All of this is only done if
we are running under Valgrind.
https://bugzilla.gnome.org/show_bug.cgi?id=698595
gtk# also has a problem with the new interface-after-init restriction
that nobody noticed until now. Add an exception for them as well so
that they have a cycle or so to sort things out.
https://bugzilla.gnome.org/show_bug.cgi?id=687659
glibmm has a pretty difficult-to-solve problem caused by our recent
change to deny addition of interfaces to classes after initialisation.
They're looking for a long-term workaround for the problem, but in the
meantime we can allow the registration to succeed (with warning) if the
class looks like it's being defined by gtkmm.
https://bugzilla.gnome.org/show_bug.cgi?id=697229
Flags being used in the G_DEFINE_TYPE_EXTENDED sample was "0", so it
should expand to 0 as well, otherwise the compiler would bark with:
maman-bar.c: In function ‘maman_bar_get_type’:
maman-bar.c:36:53: error: ‘flags’ undeclared (first use in this function)
maman-bar.c:36:53: note: each undeclared identifier is reported only once for each function it appears in
https://bugzilla.gnome.org/show_bug.cgi?id=697250
Some (broken) toolchains for example trip up
-Werror=missing-prototypes in system headers. This patch allows
people to skip the formerly hardcoded "baseline" warnings.
https://bugzilla.gnome.org/show_bug.cgi?id=694757
When looking up signals by name (to connect, for example) and the named
signal cannot be found on the given instance, report the type of the
instance.
This is quite a lot more useful as a diagnostic message than only a
memory address.
https://bugzilla.gnome.org/show_bug.cgi?id=694350
We need to keep a reference to the handler in the fast path, just like
in the slow path, otherwise if another thread disconnects the handler
we may destroy the closure while we're using it without the lock held.
We also move the freeing of the instance to after the emission is totally
done as the handler_unref_R (and the tracepoint) reference it.
https://bugzilla.gnome.org/show_bug.cgi?id=694253
handler_ref and handler_unref_R are always called with the signal
lock held. This is obvious for handler_unref_R as it even sometimes
drops this lock, and can be verified quickly for handler_ref by looking
at all call sites.
This improves the performace about 6% on the emit-handled and the
emit-handled-generic tests.
https://bugzilla.gnome.org/show_bug.cgi?id=694253
Experimentally disable the ability to unload dynamic types by refusing
to drop the last reference on types (effectively turning the type
unloading into dead code).
The plan is to leave things like this for a stable cycle and only
proceed with removing the code if we are sure that there are no
unforeseen problems.
https://bugzilla.gnome.org/show_bug.cgi?id=693351
The point of g_source_set_closure() is getting memory management right,
including handling closures disappearing from the outside (for example
because a runtime they refer to is being shutdown). This means that
sources with an associated closure should remove themselves from the
main loop and free memory when the closure is invalidated.
https://bugzilla.gnome.org/show_bug.cgi?id=692034
Before this commit, the only difference between the expected and actual
ABI were the addition of _init and _fini symbols in each module (now
that regexp-based export control is not catching those).
This is the bug that has been causing segfaults and criticals when accel
keys are used to close windows via GtkUIManager.
The main cause of this problem was a mistake made in the original patch
when modifying the handler_lookup() to take the extra 'closure'
parameter. The original check used was:
if (handler->sequential_number == handler_id ||
(closure && handler->closure == closure))
It was called to find a particular closure like so:
handler_lookup (instance, 0, closure, &signal_id);
The problem is that the check will return if either the signal ID or
closure matches (if a closure was given). The calling code assumes 0 to
be an invalid signal ID which will match no handlers, but unfortunately
the rest of gsignal code uses this to denote a signal that has already
been disconnected. The result is that this function was searching for a
matching closure _or_ the first already-disconnected handler. When it
found the already-disconnected handler, we'd get criticals and crashes.
The condition has been corrected; it now ignores the handler_id
parameter if the closure parameter is non-NULL.
While we're in here, change the lifecycle of the invalidation notify to
be easier to understand.
Before, the notify was removed when the last reference on the handler
dropped. This could happen in very many situations; often at the end of
an emission. Instead, we now tie the registration of the notifier to
the lifecycle of the signal connection. When the signal is disconnected
we remove the notification, even if other references are held (eg:
because it is currently being dispatched).
https://bugzilla.gnome.org/show_bug.cgi?id=690118
This reverts commit f2e00a07f4.
Moving the block up would prevent G_OS_WIN32 being checked correctly as
it is a macro that is defined by including the GLib header(s), at least for
Visual C++ builds.
https://bugzilla.gnome.org/show_bug.cgi?id=691769
We only want to control the default visibility for our five main
installable libraries: libglib, libgthread, libgmodule, libgobject,
libgio. We should therefore only set -fvisibility=hidden when building
those.
Use a separate substitution variable for this purpose.
Using CFLAGS directly leads to some modules built in testcases not
exporting their symbols (and then the tests fail). It also affects the
fam file monitoring module.
Colin had originally done it this way in his visibility patch series but
I failed to understand why so I didn't copy it. Now I do.
Also: revert changes made to two testcases in an attempt to work around
this issue.
https://bugzilla.gnome.org/show_bug.cgi?id=691756
Commit 282366c326 unnecessarily (skip)ed all the GParamSpec constructors like
g_param_spec_bool(). Make those introspectable by dropping the (skip) and
adding proper transfer annotations.
Keep g_param_spec_value_array() skipped as GValueArray is deprecated.
With visibility now under the control of __declspec(dllexport) we no
longer need to build .def files or use them for building our various
.dll files.
.def files used to be installed (even though it is only really useful
when creating the .dll or .lib file). Don't do that anymore either.
The Makefiles still contain rules to create a .lib file for use with
Visual Studio and these rules require .def files. There are special
requirements to using these rules (like having installed and setup
Microsoft tools for use during the build) and therefore the problem of
creating a .def file for use with them is left open to anyone willing to
make the effort. Many options are available depending on which
toolchain is in use (dlltool, pexport, gendef, dumpbin.exe, just to name
a few).
If we can find a free tool for creating .lib files in the future, we
should probably revisit this issue and add proper support back to our
build system.