Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dt_dev_history_snapshot_t Struct Reference

A reference-sharing snapshot of dev->history, for readers that outlive a lock. More...

#include <dev_history.h>

+ Collaboration diagram for dt_dev_history_snapshot_t:

Data Fields

GList * items
 
int32_t history_end
 
uint64_t history_hash
 

Detailed Description

A reference-sharing snapshot of dev->history, for readers that outlive a lock.

The pipe resync is O(nodes x history) and runs every module's commit_params(): tens of ms routinely, over 200 ms under mask-heavy history. Holding history_mutex as reader for all of it starves the GUI thread's writer for the same duration on every edit, and glibc's writer-preferring policy then blocks every NEW reader too, so one slow resync stalls the whole application on the next commit. A snapshot ends that: take the read lock, copy the list and reference each item, capture history_end and the hash that were written together with it, release the lock – microseconds – and resync against the snapshot instead.

Nothing is deep-copied. dt_dev_history_cow_touch() is the writer's side of this contract: an item whose refcount is above 1 is cloned before it is mutated in place, so a snapshot never observes a half-rewritten item, and dt_history_duplicate() is not needed here.

history_end and history_hash are captured under the same lock as the list because dt_dev_set_history_end_ext() writes them together: the three describe one committed state. Reading the hash after releasing the lock would let a commit land in between and mark the pipe as synced to history it never resynced against.

Definition at line 142 of file dev_history.h.

Field Documentation

◆ history_end

◆ history_hash

uint64_t dt_dev_history_snapshot_t::history_hash

◆ items


The documentation for this struct was generated from the following file: