Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-08-04 - [Avoid Eager Cloning from Mutex]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the one-off .jules root bucket

This commit creates a new top-level directory solely for a task-specific automation note, rather than a durable category of project content. Keeping this artifact makes the repository structure less predictable and leaves an unowned document that can become stale; omit it instead of introducing .jules/.

AGENTS.md reference: AGENTS.md:L131-L131

Useful? React with πŸ‘Β / πŸ‘Ž.

**Learning:** Eagerly cloning large data structures (like a 64KB scrollback string) out of a `Mutex` just to pass to read-only functions causes significant unnecessary heap allocations during hot paths like terminal spawn.
**Action:** Keep the processing logic inside the lock's scope (using `.and_then` or `.is_some_and`) and borrow the value with `.as_deref()` to eliminate redundant heap allocations.
35 changes: 16 additions & 19 deletions crates/forktty-ui-gtk/src/gtk_app/controller/embedded_spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,17 @@ impl TerminalController {
&surface_id,
generation,
|| {
let stored = model.lock().ok().and_then(|model| {
model
let bytes = model.lock().ok().and_then(|model| {
let stored = model
.surface(&surface_id)
.and_then(|surface| surface.persisted_scrollback.clone())
.and_then(|surface| surface.persisted_scrollback.as_deref());
embedded_scrollback_restore_bytes(
persistent_scrollback_lines,
embedder.supports_restore_scrollback(),
stored,
)
});
if let Some(bytes) = embedded_scrollback_restore_bytes(
persistent_scrollback_lines,
embedder.supports_restore_scrollback(),
stored.as_deref(),
) {
if let Some(bytes) = bytes {
if let Err(err) =
unsafe { embedder.restore_scrollback(&widget, &bytes) }
{
Expand Down Expand Up @@ -483,21 +484,17 @@ impl TerminalController {
let model = self.model.clone();
let surface_id = request.surface_id.clone();
let weak_widget = widget.downgrade();
let mut skip_initial_snapshot = model
.lock()
.ok()
.and_then(|model| {
model
.surface(&surface_id)
.and_then(|surface| surface.persisted_scrollback.clone())
})
.as_deref()
.is_some_and(|persisted_scrollback| {
let mut skip_initial_snapshot = model.lock().ok().is_some_and(|model| {
let stored = model
.surface(&surface_id)
.and_then(|surface| surface.persisted_scrollback.as_deref());
stored.is_some_and(|persisted_scrollback| {
should_skip_initial_embedded_scrollback_snapshot(
embedder.supports_restore_scrollback(),
Some(persisted_scrollback),
)
});
})
});
let mut last_snapshot: Option<String> = None;
glib::timeout_add_local(EMBEDDED_GHOSTTY_SCROLLBACK_SNAPSHOT_INTERVAL, move || {
let Some(widget) = weak_widget.upgrade() else {
Expand Down
Loading