navidrome/conf
Deluan Quintão fc9cdf39c8
fix(conf): make Dir a plain value type to prevent sync.Once corruption (#5543)
Dir embedded sync.Once directly and exposed a value-receiver GoString so
that pretty.Sprintf("%# v", Server) could render the path. That meant
every pretty-print copied the entire Dir along with its Once, and a
goroutine concurrently using the original (or any copy) for Path() could
hit a "sync: unlock of unlocked mutex" runtime fatal error. The failure
was reproduced deterministically on Windows CI when test-suite shuffle
ordering raced cache initialization (utils/cache/file_caches.go's
NewFileCache.func1 -> conf.CacheFolder.MustPath) against the
configuration-dump pretty.Sprintf in Load().

Drop the sync.Once entirely. Dir is now a plain {path, perm} value type,
and Path() calls os.MkdirAll on every invocation. MkdirAll is
idempotent, so repeated calls on an existing directory cost one stat
syscall — negligible for the few config paths read at startup and during
cache init.

This removes the entire class of bug:
  - No Mutex, so copies (via reflection, pretty-print, etc.) are safe.
  - No state pointer, so no nil-state defensive checks scattered across
    methods, and no risk of two copies seeing different lifecycle state.
  - go vet is happy with the value receivers — the //nolint:govet
    suppression on GoString is gone.

Adds two regression tests in conf/dir_test.go:
  - GoString renders Dir as a quoted path under pretty.Sprintf (and
    does not leak the internal struct fields).
  - Concurrent copy + Path() stress test, locking in the copy-safety
    property in case the type ever grows non-trivial state again.
2026-05-27 23:18:35 -03:00
..
buildtags feat(server): implement FTS5-based full-text search (#5079) 2026-02-21 17:52:42 -05:00
configtest refactor(conf): replace eager dir creation with lazy Dir type (#5495) 2026-05-13 17:44:22 -03:00
mime fix(ui): service worker does not load new version of ui (#3402) 2024-10-16 21:39:14 -04:00
testdata feat: accept ND_-prefixed env var names in config files (#5258) 2026-03-28 13:17:31 -04:00
configuration.go refactor(transcoding): rename EnableTranscodingCancellation to Transcoding.EnableCancellation (#5523) 2026-05-24 00:51:58 -03:00
configuration_test.go refactor(conf): replace eager dir creation with lazy Dir type (#5495) 2026-05-13 17:44:22 -03:00
dir.go fix(conf): make Dir a plain value type to prevent sync.Once corruption (#5543) 2026-05-27 23:18:35 -03:00
dir_test.go fix(conf): make Dir a plain value type to prevent sync.Once corruption (#5543) 2026-05-27 23:18:35 -03:00
export_test.go feat(server): add EnforceNonRootUser config option to exit early if started as root (#5373) 2026-04-21 21:27:54 -04:00