You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(multisync): apply sync destination changes without restarting fppd
Ticking a per-remote Unicast checkbox on the MultiSync page, or toggling any
of the send-method checkboxes, flagged fppd as needing a restart. It never
had to: fppd already re-reads the settings file whenever the web UI writes it
(FileMonitor in fppd.cpp), and settings.cpp already has a listener mechanism
for reacting to individual keys. The only thing missing was rebuilding the
destination list those settings feed, which OpenControlSockets() did once at
startup and never again.
Split that parsing out into ReloadSyncDestinations() and register it against
MultiSyncRemotes, MultiSyncExtraRemotes and the three send-method settings.
Hostnames are resolved into a local vector first, since getaddrinfo() is an
unbounded lookup and the send path takes m_socketLock on the output thread
every frame; the sockaddr and mmsghdr vectors are then swapped in together
under that lock, because each mmsghdr points at its own element of the
sockaddr vector and the pair must never be observed half-updated. The rebuild
holds the same lock UpdateUnicastDestinations() uses, so the "all known
remotes" list can't read the static list for its dedupe set mid-swap. The
three send-method flags become atomic: the output thread reads them without
holding anything. Listeners are unregistered in ShutdownSync(), which is
idempotent because the destructor calls it again at static-destruction time;
that also acts as a barrier, since unregistering takes the listener list's
write lock that the firing loop holds while a callback runs.
Two bugs found in the parsing while moving it:
- Hostnames have never worked. A 2020 refactor rewrote "does this contain a
letter" as `find_if(...) == s.end()`, which is the opposite test, so
hostnames took the inet_addr() path, came back INADDR_NONE, and were then
installed as a destination of 255.255.255.255 -- every entry that wasn't
already a dotted quad silently broadcast its sync packets. An unparseable
address is now rejected and logged instead of becoming that destination.
- Clearing the remote list stored a literal pair of quote characters, since
the page PUTs the value as a JSON string. That parsed as a hostname and
cost a full DNS timeout (~4s) on every load. Tokens are unquoted first.
Verified on a single-core ARM player. Sync destinations, with tcpdump running
across a settings change mid-playback and no restart: packets to the first
loopback address stop, the reload logs, packets to the second start, all
within 250ms and all under one fppd pid -- the new destination starts and the
old one stops. Hostname handling: a remote entered as "localhost" now sends to
127.0.0.1 rather than the broadcast address, and a malformed dotted quad
yields zero destinations instead of one bad one. In headless Chrome, clicking
a per-remote Unicast checkbox raises no restart banner in 60 samples over 15s
(one flash before this change) and the checkbox survives every table re-render.
Fixes#2834
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: www/settings.json
-4Lines changed: 0 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -2365,7 +2365,6 @@
2365
2365
"description": "Send MultiSync to ALL remotes via Broadcast",
2366
2366
"tip": "Use a network broadcast to send MultiSync messages to all remotes.",
2367
2367
"type": "checkbox",
2368
-
"restart": 2,
2369
2368
"fppModes": [
2370
2369
"player"
2371
2370
],
@@ -2379,7 +2378,6 @@
2379
2378
"description": "Send MultiSync to ALL KNOWN remotes via Unicast",
2380
2379
"tip": "Unicast MultiSync messages individually to every known FPP remote that is running in Remote mode. Remotes are added to the list automatically as they are discovered (via mDNS or the normal FPP discovery). Non-FPP devices (WLED, ESPixelStick, Falcon controllers, etc.) and FPP instances not in Remote mode are skipped. Useful when multicast/broadcast is unreliable across your network.",
"tip": "FPP will send unicast MultiSync discovery messages to the IPs in this list to allow discovery of devices which are unable to be discovered via FPP's normal multicast discovery. This may include systems on remote networks or connected to certain routers which do not pass multicast packets between wired and wireless interfaces.",
2444
2442
"level": 1,
2445
-
"restart": 2,
2446
2443
"size": 64,
2447
2444
"maxlength": 128,
2448
2445
"type": "text",
@@ -2495,7 +2492,6 @@
2495
2492
"description": "Send MultiSync to ALL remotes via Multicast (239.70.80.80)",
2496
2493
"tip": "Send MultiCast to 239.70.80.80 to send MultiSync messages to all remotes.",
0 commit comments