diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 8850c611c3..8b5d32b417 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -2707,28 +2707,39 @@ LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id, /*static*/ void LLLiveLSLEditor::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, bool isRunning) { - LLSD floater_key; - floater_key["taskid"] = taskId; - floater_key["itemid"] = itemId; + // This callback runs directly on the upload coprocedure's fiber + // (AssetInventoryUploadCoproc), not on the main coroutine. The work + // below eventually touches UI (selectFirstError() -> onErrorList() -> + // LLTextBase::reflow() -> LLScriptEditorSyntaxWorker::pump(), which + // takes an LLMutex) and LLMutex asserts/crashes if locked off the main + // coro. Shuttle the whole callback back to the main thread first, via + // LLAppViewer::postToMainCoro() (see llappviewer.h). + LLAppViewer::instance()->postToMainCoro( + [itemId, taskId, newAssetId, response, isRunning]() mutable + { + LLSD floater_key; + floater_key["taskid"] = taskId; + floater_key["itemid"] = itemId; - LLLiveLSLEditor* preview = LLFloaterReg::findTypedInstance("preview_scriptedit", floater_key); - if (preview) - { - preview->mItem->setAssetUUID(newAssetId); - preview->mScriptEd->setAssetID(newAssetId); + LLLiveLSLEditor* preview = LLFloaterReg::findTypedInstance("preview_scriptedit", floater_key); + if (preview) + { + preview->mItem->setAssetUUID(newAssetId); + preview->mScriptEd->setAssetID(newAssetId); - // Bytecode save completed - if (response["compiled"]) - { - preview->callbackLSLCompileSucceeded(taskId, itemId, isRunning); - } - else - { - preview->callbackLSLCompileFailed(response["errors"]); - } - response["is_running"] = isRunning; - preview->sendCompileResults(response); - } + // Bytecode save completed + if (response["compiled"]) + { + preview->callbackLSLCompileSucceeded(taskId, itemId, isRunning); + } + else + { + preview->callbackLSLCompileFailed(response["errors"]); + } + response["is_running"] = isRunning; + preview->sendCompileResults(response); + } + }); } // virtual diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 62062de755..2d30f51411 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4873,7 +4873,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de { found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, uv, normal, tangent); - if (found && !pick_transparent) + if (found && !pick_transparent && intersection) { gDebugRaycastIntersection = *intersection; }