darktable-org / darktable-org/darktable

`denoiseprofile`: variance readout written on a pipe thread, read on the GTK thread, no lock

Open
#22,061 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

scope: threading scope: UI
Dominant language
C
Stars
13.1k
Forks
1.4k
Avg merge
22h 14m
Merged PRs (30d)
198

Description

Summary

Three floats in gui_data are written from a pixelpipe thread and read from a GTK draw
callback, with no critical section on either side.

The two sides

Writer, process_variance() (1890), called from process() (2615), so a pipe thread:

  g->variance_R = var[0];    /* 1946 */
  g->variance_G = var[1];    /* 1947 */
  g->variance_B = var[2];    /* 1948 */

No dt_iop_gui_enter_critical_section() anywhere in the function. The function does
guard on g == NULL and returns early on the preview pipe (1903-1907), so the writes
happen on the full and export-style pipes when a GUI exists.

Reader, denoiseprofile_draw_variance() (3178), a GTK draw callback:

  if(!dt_isnan(g->variance_R))                    /* 3185 */
    gchar *str = g_strdup_printf("%.2f", g->variance_R);   /* 3187 */

and likewise for _G (3193, 3195) and _B (3201, 3203). Also unlocked.

Impact

A torn or stale read of a float, and a NaN check that can pass on the check and then
read a different value on the use — the reader loads each field twice (3185 then 3187).
The displayed number can be wrong or the branch inconsistent with the value printed.

Low severity: the consequence is a wrong readout, not a crash. It is listed because it
is the shape the documentation warns about, in a module that otherwise looks careful.

Suggested fix

Snapshot the three values into locals inside one critical section on the reading side,
and write them inside one on the writing side. They are plain scalars, so the span in
which they must stay valid ends at the load; a short section is sufficient and correct.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the denoiseprofile module and inspect process_variance() called from process(), alongside the denoiseprofile_draw_variance() GTK callback. Trace the existing critical-section conventions, then verify that the variance values are consistently synchronized and that the readout remains correct without check/use races.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
desktop
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.