Skip to content

book: add "Don't keep locks while emitting signals" section#2301

Open
mvanhorn wants to merge 1 commit into
gtk-rs:mainfrom
mvanhorn:osc/392-locks-and-signals
Open

book: add "Don't keep locks while emitting signals" section#2301
mvanhorn wants to merge 1 commit into
gtk-rs:mainfrom
mvanhorn:osc/392-locks-and-signals

Conversation

@mvanhorn
Copy link
Copy Markdown

Closes #392.

Summary

#392 asked for a small section in the signals chapter explaining why a
RefCell borrow (or a Mutex guard) must not be held across signal
emission, with a self-contained example that demonstrates the problem
and the fix. The maintainer's suggestion in the thread was to use a
String-typed property as the easiest way to surface the issue.

What's in the listing

book/listings/g_object_signals/3/:

  • tracked_button/imp.rs - a custom button with a text: RefCell<String> property. ButtonImpl::clicked clones the String
    out of the RefCell first, drops the borrow, and only then calls
    emit_by_name::<()>("text-changed", &[&snapshot]). An
    ANCHOR: clicked_good block delimits the part the chapter pulls in
    via {{#rustdoc_include ...}}.
  • tracked_button/mod.rs - the public wrapper, mirroring the listing-2
    shape exactly.
  • main.rs - the handler intentionally calls back into the button by
    calling set_text from inside text-changed. This is the load-
    bearing detail: it only works because clicked dropped the borrow
    before emitting. If the borrow had survived, the inner set_text
    would have aborted at BorrowMutError. An ANCHOR: handler block
    delimits the embedded snippet for the chapter.

What's in the chapter

book/src/g_object_signals.md gets a "Don't keep locks while emitting
signals" section just before the closing summary. It states the rule
once, embeds the clicked_good snippet, embeds the handler, and
explains why the fact that the handler doesn't panic is the actual
demonstration of the rule. It also notes that property notifications go
through the same dispatch path, so the same rule applies to notify.

Wiring

book/listings/Cargo.toml gets a g_object_signals_3 [[bin]] entry
between the existing g_object_signals_2 and g_object_subclassing_1,
matching the existing format.

Verification

  • The new files mirror listing 2's layout (mod.rs wrapping imp,
    imp.rs deriving Properties + glib::object_subclass + signals
    via OnceLock<Vec<Signal>>, glib::derived_properties on
    ObjectImpl).
  • I could not run cargo check locally because GTK 4 system libraries
    (gtk4.pc, pkg-config) aren't available on this machine; I tracked
    the existing patterns line-for-line against listings/g_object_signals/2/
    and book/listings/Cargo.toml so the wiring matches what the rest of
    the book does.
  • The chapter rendering uses the same {{#rustdoc_include ../listings/...}} mechanism the rest of the chapter already uses,
    with named anchors (clicked_good, handler) that match the
    existing object_impl/button_impl/signal_handling style.

If anything fails to compile under GTK 4, happy to amend - the example
is small enough to iterate quickly.

Out of scope

  • I did not add a "broken on purpose" listing. The section explains the
    bad pattern in prose and shows the good pattern in code, which keeps
    the listing buildable as part of g_object_signals_3 and avoids
    cluttering the book's cargo check with an example that's expected
    to panic.
  • No changes to the existing g_object_signals_1 / _2 listings.

gtk-rs#392 asked for a small section in the signals chapter explaining why
RefCell/Mutex must not be held across signal emission, with a
self-contained example that demonstrates the problem and the fix.

Adds a TrackedButton listing under book/listings/g_object_signals/3/
with a String property in a RefCell. ButtonImpl::clicked clones the
String out of the RefCell first, drops the borrow, and only then calls
emit_by_name. The handler in main.rs deliberately calls back into the
button via set_text from inside text-changed, which only works because
the borrow was dropped before emission - a direct demonstration of the
re-entry the section warns about.

Wires the listing into book/listings/Cargo.toml as g_object_signals_3
and adds a 'Don't keep locks while emitting signals' section in
book/src/g_object_signals.md just before the closing summary.

The example follows the maintainer suggestion to use a String-typed
property as the easiest way to surface the issue (sdroege's comment on
the issue thread).

Closes gtk-rs#392
@mvanhorn mvanhorn requested a review from Hofer-Julian as a code owner May 10, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a section about keeping locks while emitting signals

1 participant