@@ -2040,56 +2040,68 @@ void LLPreviewLSL::onSave(void* userdata, bool close_after_save)
20402040 self->saveIfNeeded ();
20412041}
20422042
2043- /* static */
2043+ // static
20442044void LLPreviewLSL::finishedLSLUpload (LLUUID itemId, LLSD response)
20452045{
2046- // Find our window and close it if requested.
2047- LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>(" preview_script" , LLSD (itemId));
2048- if (preview)
2049- {
2050- // Bytecode save completed
2051- if (response[" compiled" ])
2052- {
2053- preview->callbackLSLCompileSucceeded ();
2054- }
2055- else
2046+ // This callback runs on the upload coprocedure fiber, not the main coro.
2047+ // UI work downstream (selectFirstError -> reflow -> LLMutex::lock) asserts
2048+ // if called off the main coro, so shuttle everything back first.
2049+ LLAppViewer::instance ()->postToMainCoro (
2050+ [itemId, response]()
20562051 {
2057- preview->callbackLSLCompileFailed (response[" errors" ]);
2058- }
2059- preview->sendCompileResults (response);
2060- }
2052+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>(" preview_script" , LLSD (itemId));
2053+ if (preview)
2054+ {
2055+ if (response[" compiled" ])
2056+ {
2057+ preview->callbackLSLCompileSucceeded ();
2058+ }
2059+ else
2060+ {
2061+ preview->callbackLSLCompileFailed (response[" errors" ]);
2062+ }
2063+ preview->sendCompileResults (response);
2064+ }
2065+ });
20612066}
20622067
2068+ // static
20632069bool LLPreviewLSL::failedLSLUpload (LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)
20642070{
2065- LLSD floater_key;
2066- if (taskId.notNull ())
2067- {
2068- floater_key[" taskid" ] = taskId;
2069- floater_key[" itemid" ] = itemId;
2070- }
2071- else
2072- {
2073- floater_key = LLSD (itemId);
2074- }
2075-
2076- LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>(" preview_script" , floater_key);
2077- if (preview)
2078- {
2079- // unfreeze floater
2080- LLSD errors;
2081- errors.append (LLTrans::getString (" UploadFailed" ) + reason);
2082- preview->callbackLSLCompileFailed (errors);
2083-
2084- LLSD message;
2085- message[" compiled" ] = false ;
2086- message[" errors" ] = errors;
2087- preview->sendCompileResults (message);
2071+ // Same issue: this fires on the upload fiber, not the main coro.
2072+ // Note: return value is lost when posting async, but the original callers
2073+ // ignore it in the upload path anyway.
2074+ LLAppViewer::instance ()->postToMainCoro (
2075+ [itemId, taskId, response, reason]()
2076+ {
2077+ LLSD floater_key;
2078+ if (taskId.notNull ())
2079+ {
2080+ floater_key[" taskid" ] = taskId;
2081+ floater_key[" itemid" ] = itemId;
2082+ }
2083+ else
2084+ {
2085+ floater_key = LLSD (itemId);
2086+ }
20882087
2089- return true ;
2090- }
2088+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>(" preview_script" , floater_key);
2089+ if (preview)
2090+ {
2091+ LLSD errors;
2092+ errors.append (LLTrans::getString (" UploadFailed" ) + reason);
2093+ preview->callbackLSLCompileFailed (errors);
2094+
2095+ LLSD message;
2096+ message[" compiled" ] = false ;
2097+ message[" errors" ] = errors;
2098+ preview->sendCompileResults (message);
2099+ }
2100+ });
20912101
2092- return false ;
2102+ // Return value is meaningless now that we're async, but the signature
2103+ // requires it. The upload infrastructure doesn't use it either.
2104+ return true ;
20932105}
20942106
20952107// Save needs to compile the text in the buffer. If the compile
0 commit comments