server : fix deadlock when removing a finished download

The download monitor thread acquires the mutex on its way out, so joining
it while holding the lock in server_models::remove deadlocks once the
status has flipped to DOWNLOADED. Join outside the lock, same pattern as
load_models().

Assisted-by: pi:zai-org/GLM-5.3
This commit is contained in:
Aleksander Grygier
2026-09-07 22:10:08 +02:00
parent a56cfe1bcf
commit cdc2053bf7
+13 -5
View File
@@ -1320,14 +1320,22 @@ bool server_models::remove(const std::string & name) {
return true;
}
// join before erasing - thread no longer acquires this mutex
if (it->second.th.joinable()) {
it->second.th.join();
// on the cancelled-download path the status flips to DOWNLOADED while the
// monitoring thread still has a mutex-guarded step left, so joining under
// the lock would deadlock - join outside, as load_models() does
std::thread th = std::move(it->second.th);
mapping.erase(name);
lk.unlock();
// join first so the monitoring thread's final mutex-guarded cleanup cannot
// race the disk removal, then remove from disk without holding the lock
// (best-effort: cancelled downloads may have no cached files)
if (th.joinable()) {
th.join();
}
// remove from disk (best-effort: cancelled downloads may have no cached files)
bool ok = common_download_remove(name);
mapping.erase(name);
if (!ok) {
SRV_WRN("removing model name=%s from disk returned false (no cached files?)\n", name.c_str());
}