Global Variables

A handful of global structures carry state across the whole application. Know these before you start; misuse of them (especially the locks) has caused real shipped bugs.

gfit

gfit is the currently loaded image. It is declared in src/core/siril.h.

Changed in version 1.5: gfit is now a pointer: extern fits *gfit;. In 1.4 it was a value: extern fits gfit;. When porting an old patch, &gfit becomes gfit and params->fit = &gfit; becomes params->fit = gfit;.

The fits structure (struct ffit) holds the pixel data (data for 16-bit, fdata for float — the two are mutually exclusive, selected by type), the per-layer pointers (pdata / fpdata), the FITS keywords, the statistics cache (stats), the ICC profile, an optional image mask (see Masks), and — as its last member — a read/write lock.

The fits rwlock

Every fits embeds a GRWLock rwlock as its last field (a static assertion enforces the position). It guards concurrent access to the pixel data and metadata of public fits — currently only gfit — from the processing worker and from Python connection threads.

The rules, transcribed from the comment in siril.h:

  • Locking is done in high-level code only: the generic workers (Generic workers), the simple threaded functions run directly via start_in_new_thread, and the Python command handlers.

  • It must not be taken in low-level fits-handling functions (format loaders, copyfits, direct data/fdata manipulation). Locking there is likely to cause deadlocks.

  • The lock is initialised for free by calloc/zero-init of the fits, and is never copied or overwritten by copyfits().

  • Always unlock with the same flavour you locked (g_rw_lock_reader_lockg_rw_lock_reader_unlock). GLib does not assert on mismatch, and a reader-lock/writer-unlock mismatch has shipped as a data-corruption bug.

Important

Worker hooks run with the fits already locked on your behalf by the worker. An image_hook / mask_hook must not take the fits lock on the fits it was handed — the lock is non-recursive, so you would instantly self-deadlock on the in-place path. See Locking.

com

com (struct cominf, in siril.h) is the global core state structure.

Warning

Avoid adding members to com. For state that must outlive a single operation, prefer a module-static variable in the file that owns it — the C equivalent of a class variable. Only add to com when there is no reasonable alternative.

The members you will actually reach for:

  • com.pref — the whole preferences tree (see settings.c,h). Read under the pref_rwlock reader lock, which the workers already hold for you for the duration of a job.

  • com.max_thread — the total thread budget for parallel execution. Do not read this directly inside a worker hook; use the thread count the worker hands you (see Threading).

  • com.headless — TRUE for siril-cli (no GUI at all).

  • com.script — a script is executing (always TRUE when headless).

  • com.python_script / com.python_command — a Python script is running / Python is currently running a Siril command.

  • com.seq — the currently loaded sequence.

  • com.uniq — the currently loaded single image, when not in a sequence.

  • com.selection — the selection rectangle (all four fields are updated atomically under com.mutex).

  • com.wd — the working directory.

  • com.stars — the detected star list (guarded by com.stars_lock).

Locks that live in com

Several synchronisation primitives are members of com: com.mutex, com.env_mutex, com.histogram_mutex, com.pref_rwlock and com.stars_lock. Their duties, who may take them and — critically — where they must not be taken are documented once, authoritatively, in Locking. Do not reason about them from here; that chapter is the single source of truth (it also covers the per-fits rwlock above).

gui

gui (struct guiinf, now in src/gui-gtk4/gui_state.h) holds GTK-side display state: the per-viewport image views and tiles, zoom, the ROI, render buffers and their cairo_mutex.

Changed in version 1.5: guiinfo moved out of siril.h into src/gui-gtk4/gui_state.h as part of the GUI separation. It is never referenced outside src/gui-gtk4. Core code that needs a GUI effect goes through gui_iface instead — see gui_iface in depth.