gobject: add g_object_weak_ref_sync() for thread-safe weak notifications

We have g_object_weak_ref(), which is documented to be not thread-safe.

Note that "not thread-safe" here is not quite complete. The object is
still alive (or semi-alive right before finalize()) inside the
notification callback. There is no problem with accessing the object,
even taking references (resurrection). What is not thread-safe, is to
know that when we call g_object_weak_unref(), that a concurrent thread
doesn't currently invoke the callback. And to agree on whether the
callback was invoked (once) or whether we unsubscribed it first.
Usually, you would find it hard to hit that race, because you need a
strong reference to the object to call g_object_weak_unref(), so how
could another thread have the weak notifications running? By
g_object_run_dispose().

There are multiple solutions. Commonly, we would combine
g_object_weak_ref() with GWeakRef, but that does nothing about
g_object_run_dispose(), because with g_object_run_dispose() the object
ref count is not ever going below one. Also, GWeakRef has the downside of
requiring a strong reference (which might emit toggle notifications).

Another solution is g_object_weak_ref_full() with a GDestroyNotify. The
destroy notify callback is guaranteed to be called at most once, either
by after the weak notificaiton or during g_object_weak_unref_full().
This works even with g_object_run_dispose(). The problem is that is can
be cumbersome to implement this correctly (the callbacks and the caller
of g_object_weak_unref_full() must handle this and add a proper
thread-safe mechanism themselves). The upside is, that the callback is
invoked without a lock, so it is not error prone to dead-lock.

Now add g_object_weak_ref_sync(). This invokes the weak notificaiton
while holding a lock. And g_object_weak_unref_sync() will wait on the
same lock. That means, we can atomically know that the notification is
called at most once, while not requiring GWeakRef (or strong references)
or additional synchonization. The downside is the very possibility of
dead-lock. The caller must be careful to not take a lock, that is also
held by another thread which also tries to call
g_object_weak_unref_sync().
3 files changed
tree: 30b9ed7e5612d5b063fc803c8cd849048ee848fe
  1. .gitlab-ci/
  2. .reuse/
  3. docs/
  4. fuzzing/
  5. gio/
  6. girepository/
  7. glib/
  8. gmodule/
  9. gobject/
  10. gthread/
  11. LICENSES/
  12. m4macros/
  13. po/
  14. subprojects/
  15. tests/
  16. tools/
  17. .clang-format
  18. .dir-locals.el
  19. .editorconfig
  20. .gitignore
  21. .gitlab-ci.yml
  22. .gitmodules
  23. .lcovrc
  24. CODE_OF_CONDUCT.md
  25. CONTRIBUTING.md
  26. glib.doap
  27. INSTALL.md
  28. meson.build
  29. meson.options
  30. NEWS
  31. README.md
  32. SECURITY.md
README.md

GLib

GLib is the low-level core library that forms the basis for projects such as GTK and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system.

The official download locations are: https://download.gnome.org/sources/glib

The official web site is: https://www.gtk.org/

Installation

See the file ‘INSTALL.md’. There is separate and more in-depth documentation for building GLib on Windows.

Supported versions

Upstream GLib only supports the most recent stable release series, the previous stable release series, and the current development release series. All older versions are not supported upstream and may contain bugs, some of which may be exploitable security vulnerabilities.

See SECURITY.md for more details.

Documentation

API documentation is available online for GLib for the:

Discussion

If you have a question about how to use GLib, seek help on GNOME’s Discourse instance. Alternatively, ask a question on StackOverflow and tag it glib.

Reporting bugs

Bugs should be reported to the GNOME issue tracking system. You will need to create an account for yourself. You may also submit bugs by e-mail (without an account) by e-mailing incoming+gnome-glib-658-issue-@gitlab.gnome.org, but this will give you a degraded experience.

Bugs are for reporting problems in GLib itself, not for asking questions about how to use it. To ask questions, use one of our discussion forums.

In bug reports please include:

  • Information about your system. For instance:
    • What operating system and version
    • For Linux, what version of the C library
    • And anything else you think is relevant.
  • How to reproduce the bug.
    • If you can reproduce it with one of the test programs that are built in the tests/ subdirectory, that will be most convenient. Otherwise, please include a short test program that exhibits the behavior. As a last resort, you can also provide a pointer to a larger piece of software that can be downloaded.
  • If the bug was a crash, the exact text that was printed out when the crash occurred.
  • Further information such as stack traces may be useful, but is not necessary.

Contributing to GLib

Please follow the contribution guide to know how to start contributing to GLib.

Patches should be submitted as merge requests to gitlab.gnome.org. Note that you will need to be logged in to the site to use this page. If the patch fixes an existing issue, please refer to the issue in your commit message with the following notation (for issue 123):

Closes: #123

Otherwise, create a new merge request that introduces the change. Filing a separate issue is not required.