From 1d673df1bdef39276e4485163183354734f86132 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 29 Jan 2013 23:21:37 +0100 Subject: [PATCH] Add AIMeshUpload and fix LLMeshUploadThread * Removes polling stuff (call to gMeshRepo.update()) which did nothing but check if uploads already finished. * Just creates and runs the state machine (AIMeshUpload) instead of creating an LLThread derived class (LLMeshUploadThread) and adding that to a queue, then have the main thread start it after adding it to another queue in order to keep track of the instances (both queues are gone). * mWholeModelUploadURL was moved to the state machine, because it needs a life time till the responders finishes (can't be part of the thread object). * LLMeshUploadThread is now derived from AIThreadImpl instead of LLThread, so it can be run in a state machine thread. * The call to LLHTTPClient::post is now done from the main thread instead of from the thread, but I don't think that is a problem. --- indra/newview/llappviewer.cpp | 1 - indra/newview/llmeshrepository.cpp | 236 ++++++++++++----------------- indra/newview/llmeshrepository.h | 63 +++++--- 3 files changed, 136 insertions(+), 164 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a25086e04..0c47be8f2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1310,7 +1310,6 @@ bool LLAppViewer::mainLoop() break; } } - gMeshRepo.update() ; if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && (frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bc6f5e296..0d8e44650 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -371,27 +371,19 @@ void log_upload_error(S32 status, const LLSD& content, std::string stage, std::s class LLWholeModelFeeResponder : public LLHTTPClient::ResponderWithCompleted { - LLMeshUploadThread* mThread; + std::string& mWholeModelUploadURL; LLSD mModelData; LLHandle mObserverHandle; public: - LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle observer_handle): - mThread(thread), + LLWholeModelFeeResponder(LLSD& model_data, LLHandle observer_handle, std::string& url_out): + mWholeModelUploadURL(url_out), mModelData(model_data), mObserverHandle(observer_handle) { - if (mThread) - { - mThread->startRequest(); - } } ~LLWholeModelFeeResponder() { - if (mThread) - { - mThread->stopRequest(); - } } /*virtual*/ void completed(U32 status, @@ -411,19 +403,19 @@ public: if (((200 <= status) && (status < 300)) && cc["state"].asString() == "upload") { - mThread->mWholeModelUploadURL = cc["uploader"].asString(); + mWholeModelUploadURL = cc["uploader"].asString(); if (observer) { cc["data"]["upload_price"] = cc["upload_price"]; - observer->onModelPhysicsFeeReceived(cc["data"], mThread->mWholeModelUploadURL); + observer->onModelPhysicsFeeReceived(cc["data"], mWholeModelUploadURL); } } else { llwarns << "fee request failed" << llendl; log_upload_error(status,cc,"fee",mModelData["name"]); - mThread->mWholeModelUploadURL = ""; + mWholeModelUploadURL = ""; if (observer) { @@ -438,28 +430,18 @@ public: class LLWholeModelUploadResponder : public LLHTTPClient::ResponderWithCompleted { - LLMeshUploadThread* mThread; LLSD mModelData; LLHandle mObserverHandle; public: - LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle observer_handle): - mThread(thread), + LLWholeModelUploadResponder(LLSD& model_data, LLHandle observer_handle): mModelData(model_data), mObserverHandle(observer_handle) { - if (mThread) - { - mThread->startRequest(); - } } ~LLWholeModelUploadResponder() { - if (mThread) - { - mThread->stopRequest(); - } } /*virtual*/ void completed(U32 status, @@ -1288,22 +1270,21 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 return true; } -LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, - LLHandle fee_observer, LLHandle upload_observer) -: LLThread("mesh upload"), - mDiscarded(FALSE), - mDoUpload(do_upload), - mWholeModelUploadURL(upload_url), - mFeeObserverHandle(fee_observer), - mUploadObserverHandle(upload_observer) +LLMeshUploadThread::LLMeshUploadThread(AIStateMachineThreadBase* state_machine_thread) : AIThreadImpl(state_machine_thread, "mesh upload") { +} + +void LLMeshUploadThread::init(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, + bool upload_skin, bool upload_joints, bool do_upload, + LLHandle const& fee_observer, LLHandle const& upload_observer) +{ + mDoUpload = do_upload; + mFeeObserverHandle = fee_observer; + mUploadObserverHandle = upload_observer; mInstanceList = data; mUploadTextures = upload_textures; mUploadSkin = upload_skin; mUploadJoints = upload_joints; - mMutex = new LLMutex(); - mPendingUploads = 0; mOrigin = gAgent.getPositionAgent(); mHost = gAgent.getRegionHost(); @@ -1356,28 +1337,86 @@ void LLMeshUploadThread::preStart() } } -void LLMeshUploadThread::discard() +AIMeshUpload::AIMeshUpload(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, std::string const& upload_url, bool do_upload, + LLHandle const& fee_observer, LLHandle const& upload_observer) : mWholeModelUploadURL(upload_url) { - LLMutexLock lock(mMutex) ; - mDiscarded = TRUE ; + mMeshUpload->init(data, scale, upload_textures, upload_skin, upload_joints, do_upload, fee_observer, upload_observer); } -BOOL LLMeshUploadThread::isDiscarded() +char const* AIMeshUpload::state_str_impl(state_type run_state) const { - LLMutexLock lock(mMutex) ; - return mDiscarded ; -} - -void LLMeshUploadThread::run() -{ - if (mDoUpload) + switch (run_state) { - doWholeModelUpload(); + AI_CASE_RETURN(AIMeshUpload_start); + AI_CASE_RETURN(AIMeshUpload_threadFinished); + AI_CASE_RETURN(AIMeshUpload_responderFinished); + } + return "UNKNOWN STATE"; +} + +void AIMeshUpload::initialize_impl() +{ + mMeshUpload->preStart(); + set_state(AIMeshUpload_start); +} + +void AIMeshUpload::multiplex_impl() +{ + switch (mRunState) + { + case AIMeshUpload_start: + mMeshUpload.run(this, AIMeshUpload_threadFinished); + idle(AIMeshUpload_start); // Wait till the thread finished. + break; + case AIMeshUpload_threadFinished: + mMeshUpload->postRequest(mWholeModelUploadURL, this); + idle(AIMeshUpload_threadFinished); // Wait till the responder finished. + break; + case AIMeshUpload_responderFinished: + finish(); + break; + } +} + +bool LLMeshUploadThread::run() +{ + generateHulls(); + wholeModelToLLSD(mModelData, mDoUpload); + if (!mDoUpload) + { + ++dump_num; + dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num)); } else { - requestWholeModelFee(); + mBody = mModelData["asset_resources"]; + dump_llsd_to_file(mBody, make_dump_name("whole_model_body_", dump_num)); } + return true; // true = finish, false = abort. +} + +void LLMeshUploadThread::postRequest(std::string& whole_model_upload_url, AIMeshUpload* state_machine) +{ + if (!mDoUpload) + { + LLHTTPClient::post(mWholeModelFeeCapability, mModelData, + new LLWholeModelFeeResponder(mModelData, mFeeObserverHandle, whole_model_upload_url)/*,*/ + DEBUG_CURLIO_PARAM(debug_on), keep_alive, state_machine, AIMeshUpload_responderFinished); + } + else + { + LLHTTPClient::post(whole_model_upload_url, mBody, + new LLWholeModelUploadResponder(mModelData, mUploadObserverHandle)/*,*/ + DEBUG_CURLIO_PARAM(debug_off), keep_alive, state_machine, AIMeshUpload_responderFinished); + } +} + +void AIMeshUpload::abort_impl() +{ +} + +void AIMeshUpload::finish_impl() +{ } void dump_llsd_to_file(const LLSD& content, std::string filename) @@ -1625,40 +1664,6 @@ void LLMeshUploadThread::generateHulls() } } -void LLMeshUploadThread::doWholeModelUpload() -{ - if (mWholeModelUploadURL.empty()) - { - llinfos << "unable to upload, fee request failed" << llendl; - } - else - { - generateHulls(); - - LLSD full_model_data; - wholeModelToLLSD(full_model_data, true); - LLSD body = full_model_data["asset_resources"]; - dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); - LLHTTPClient::post(mWholeModelUploadURL, body, - new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle)); - } -} - -void LLMeshUploadThread::requestWholeModelFee() -{ - dump_num++; - - generateHulls(); - - LLSD model_data; - wholeModelToLLSD(model_data,false); - dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num)); - - // This might throw AICurlNoEasyHandle. - LLHTTPClient::post(mWholeModelFeeCapability, model_data, - new LLWholeModelFeeResponder(this, model_data, mFeeObserverHandle)); -} - void LLMeshRepoThread::notifyLoadedMeshes() {//called via gMeshRepo.notifyLoadedMeshes(). mMutex already locked while (!mLoadedQ.empty()) @@ -2134,12 +2139,6 @@ void LLMeshRepository::shutdown() { llinfos << "Shutting down mesh repository." << llendl; - for (U32 i = 0; i < mUploads.size(); ++i) - { - llinfos << "Discard the pending mesh uploads " << llendl; - mUploads[i]->discard() ; //discard the uploading requests. - } - mThread->mSignal->signal(); while (!mThread->isStopped()) @@ -2149,18 +2148,6 @@ void LLMeshRepository::shutdown() delete mThread; mThread = NULL; - for (U32 i = 0; i < mUploads.size(); ++i) - { - llinfos << "Waiting for pending mesh upload " << i << "/" << mUploads.size() << llendl; - while (!mUploads[i]->isStopped()) - { - apr_sleep(10); - } - delete mUploads[i]; - } - - mUploads.clear(); - delete mMeshMutex; mMeshMutex = NULL; @@ -2176,27 +2163,6 @@ void LLMeshRepository::shutdown() LLConvexDecomposition::quitSystem(); } -//called in the main thread. -S32 LLMeshRepository::update() -{ - S32 size = 0; - if(mUploadWaitList.empty()) - { - return 0 ; - } - - size = mUploadWaitList.size() ; - for (S32 i = 0; i < size; ++i) - { - mUploads.push_back(mUploadWaitList[i]); - mUploadWaitList[i]->preStart() ; - mUploadWaitList[i]->start() ; - } - mUploadWaitList.clear() ; - - return size ; -} - S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) { if (detail < 0 || detail > 4) @@ -2280,22 +2246,6 @@ void LLMeshRepository::notifyLoadedMeshes() static const LLCachedControl max_concurrent_requests("MeshMaxConcurrentRequests"); LLMeshRepoThread::sMaxConcurrentRequests = max_concurrent_requests; - //clean up completed upload threads - for (std::vector::iterator iter = mUploads.begin(); iter != mUploads.end(); ) - { - LLMeshUploadThread* thread = *iter; - - if (thread->isStopped()) - { - iter = mUploads.erase(iter); - delete thread; - } - else - { - ++iter; - } - } - //update inventory if (!mInventoryQ.empty()) { @@ -2720,9 +2670,13 @@ void LLMeshRepository::uploadModel(std::vector& data, LLVector3 bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, LLHandle fee_observer, LLHandle upload_observer) { - LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url, - do_upload, fee_observer, upload_observer); - mUploadWaitList.push_back(thread); + if (do_upload && upload_url.empty()) + { + llinfos << "unable to upload, fee request failed" << llendl; + return; + } + AIMeshUpload* uploader = new AIMeshUpload(data, scale, upload_textures, upload_skin, upload_joints, upload_url, do_upload, fee_observer, upload_observer); + uploader->run(); } S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 5ee1523f5..b63a32e58 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -37,6 +37,7 @@ #include "LLConvexDecomposition.h" #include "lluploadfloaterobservers.h" +#include "aistatemachinethread.h" class LLVOVolume; class LLMeshResponder; @@ -44,6 +45,7 @@ class LLMutex; class LLCondition; class LLVFS; class LLMeshRepository; +class AIMeshUpload; class LLMeshUploadData { @@ -350,7 +352,7 @@ public: }; -class LLMeshUploadThread : public LLThread +class LLMeshUploadThread : public AIThreadImpl { private: S32 mMeshUploadTimeOut ; //maximum time in seconds to execute an uploading request. @@ -372,6 +374,8 @@ public: LLPointer mFinalDecomp; bool mPhysicsComplete; + LLSD mModelData; + LLSD mBody; typedef std::map, std::vector > hull_map; hull_map mHullMap; @@ -382,36 +386,25 @@ public: typedef std::map, instance_list> instance_map; instance_map mInstance; - LLMutex* mMutex; - S32 mPendingUploads; LLVector3 mOrigin; bool mUploadTextures; bool mUploadSkin; bool mUploadJoints; - BOOL mDiscarded ; LLHost mHost; std::string mWholeModelFeeCapability; - std::string mWholeModelUploadURL; - LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle fee_observer= (LLHandle()), LLHandle upload_observer = (LLHandle())); + LLMeshUploadThread(AIStateMachineThreadBase* state_machine_thread); ~LLMeshUploadThread(); + void init(instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool do_upload, + LLHandle const& fee_observer, LLHandle const& upload_observer); + void postRequest(std::string& url, AIMeshUpload* state_machine); - void startRequest() { ++mPendingUploads; } - void stopRequest() { --mPendingUploads; } - - virtual void run(); + /*virtual*/ bool run(); void preStart(); - void discard() ; - BOOL isDiscarded(); void generateHulls(); - void doWholeModelUpload(); - void requestWholeModelFee(); - void wholeModelToLLSD(LLSD& dest, bool include_textures); void decomposeMeshMatrix(LLMatrix4& transformation, @@ -429,6 +422,34 @@ private: bool mDoUpload; // if FALSE only model data will be requested, otherwise the model will be uploaded }; +enum AIMeshUpload_state_type { + AIMeshUpload_start = AIStateMachine::max_state, + AIMeshUpload_threadFinished, + AIMeshUpload_responderFinished +}; + +class AIMeshUpload : public AIStateMachine +{ +private: + AIStateMachineThread mMeshUpload; + std::string mWholeModelUploadURL; + +public: + AIMeshUpload(LLMeshUploadThread::instance_list& data, LLVector3& scale, + bool upload_textures, bool upload_skin, bool upload_joints, std::string const& upload_url, bool do_upload, + LLHandle const& fee_observer, LLHandle const& upload_observer); + + void setWholeModelUploadURL(std::string const& whole_model_upload_url) { mWholeModelUploadURL = whole_model_upload_url; } + +protected: + // Implement AIStateMachine. + /*virtual*/ const char* state_str_impl(state_type) const; + /*virtual*/ void initialize_impl(); + /*virtual*/ void multiplex_impl(); + /*virtual*/ void abort_impl(); + /*virtual*/ void finish_impl(); +}; + class LLMeshRepository { public: @@ -449,7 +470,6 @@ public: void init(); void shutdown(); - S32 update() ; //mesh management functions S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); @@ -477,8 +497,9 @@ public: LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle fee_observer= (LLHandle()), LLHandle upload_observer = (LLHandle())); + bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, + LLHandle fee_observer= (LLHandle()), + LLHandle upload_observer = (LLHandle())); S32 getMeshSize(const LLUUID& mesh_id, S32 lod); @@ -519,8 +540,6 @@ public: void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header); LLMeshRepoThread* mThread; - std::vector mUploads; - std::vector mUploadWaitList; LLPhysicsDecomp* mDecompThread;