Skip to content

fix(http): lock HttpServer start/restart via start_locked (Snapmaker #870 residual) - #52

Merged
aceRage merged 1 commit into
mainfrom
cursor/httpserver-start-locked-870-c921
Sep 19, 2026
Merged

aceRage merged 1 commit into
mainfrom
cursor/httpserver-start-locked-870-c921

Conversation

@aceRage

@aceRage aceRage commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Description

Surgical extract of the remaining Snapmaker/OrcaSlicer #870 lifetime/race work onto EdgeSlicer main. This does not re-land the MQTT stack already present from Snapmaker Snapmaker#847/Snapmaker#855 via Edge #22 / #28.

HttpServer::start() still created the IO server without holding m_server_mtx, and restart() called start() (including start_health_check()) while holding that lock. That raced is_healthy() on the health-check thread (UAF / double restart) and could deadlock a join of a retired health-check thread blocked in is_healthy().

Residual vs Snapmaker Snapmaker#870 (6faa813a3c)

Marker Edge main (pre this PR) This PR
MqttClient::create() + self_ weak_ptr Present (#28) no changeMQTT.cpp/.hpp untouched
tearing_down_ + cb_mtx_ / topics_mtx_ Present (#22/#28) no change
Moonraker_Mqtt::m_client_mtx + get_mqtt_client(_tls) snapshots Present (#22) no change
m_cbs_mtx Present (#22) no change
SSWCP_MachineConnect_Instance::release_pin_client + pin CallAfter Present (#28) no change
HttpServer m_server_mtx around stop() / restart() / is_healthy() Present (#22) kept
HttpServer::start_locked() Missing ported
start() / restart() hold lock across destroy+recreate; health check after unlock Missing (start() unlocked create; restart() called start() under the lock) ported
start_http_server atomic (io-thread write vs unlocked readers) Missing ported (same HttpServer files as start_locked)
SSWCP sw_mqtt_connect failure callback captures engine as weak_ptr Missing (shared_ptr self-pin) ported (callback body kept as Edge Disconnect; no Snapmaker SNAP_LOG_BATCH / session-id)

Files

  • src/slic3r/GUI/HttpServer.hpp — declare start_locked(); std::atomic<bool> start_http_server
  • src/slic3r/GUI/HttpServer.cpp — extract body; lock in start() / restart(); start_health_check() after unlock
  • src/slic3r/GUI/SSWCP.cpp — weak_ptr engine capture in sw_mqtt_connect only

Not touched: Ultra HttpServer login handlers (ResponseLoginFailed / BBL_LOGIN_LOCALHOST_URL), SSWCP Ultra unload/archive customs, RemoteSnapmaker.cpp, MQTT.cpp/.hpp, MoonRaker.cpp/.hpp.

Intentionally not ported (re-diff, not weak_ptr/CallAfter residuals)

Screenshots/Recordings/Graphs

N/A — concurrency / lifetime fix. No UI change.

Tests

  • Static residual diff vs Snapmaker Fix MQTT disconnect crash: lifetime & race fixes in MQTT/MoonRaker/HttpServer Snapmaker/OrcaSlicer#870: MQTT core markers already satisfied (table above); only HttpServer start_locked + SSWCP engine weak_ptr applied.
  • Confirmed MQTT.cpp/.hpp have zero diff.
  • Confirmed Ultra login handlers and SSWCP unload/archive paths are unchanged.
  • Full slicer binary not built here (no deps/AppImage toolchain). Health-check restart path now exercises start_locked() under m_server_mtx with start_health_check() after unlock, so is_healthy() cannot observe the torn-down gap.

Still owed on real hardware (not run in this environment):

  • Repeated MQTT WAN connect/disconnect: no crash
  • LAN MoonRaker connect/disconnect: no crash
  • App shutdown with device page open and in-flight HTTP: no crash
  • Health-check restart path: no is_healthy UAF / double restart
Open in Web Open in Cursor 

…napmaker#870 residual)

Extract start_locked() so start()/restart() hold m_server_mtx across
destroy+recreate, then start_health_check() only after the lock is
released. Make start_http_server atomic (io-thread write vs unlocked
readers). Capture the SSWCP mqtt-connect failure callback as weak_ptr
so it cannot pin MqttClient forever.

MQTT.cpp/.hpp are unchanged; core markers from Edge #22/#28 already
satisfy Snapmaker Snapmaker#870.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
@aceRage
aceRage merged commit 0d4d63a into main Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants