diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2022-02-28 21:56:25 +0200 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2022-02-28 21:56:25 +0200 | 
| commit | 1e0eafd50cc03f0796fe8678d3460aac614db603 (patch) | |
| tree | 6b9efda5d63749238a786667fc2ac4c9b3fabfad /indra/llplugin | |
| parent | 1f1d762693027a0f6ce7b913bcc8984767e947be (diff) | |
| parent | 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 (diff) | |
Merge branch 'master' into DRTVWR-544-maint
# Conflicts:
#	indra/llaudio/llstreamingaudio_fmodstudio.cpp
#	indra/newview/llviewerregion.cpp
Diffstat (limited to 'indra/llplugin')
| -rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 122 | ||||
| -rw-r--r-- | indra/llplugin/llpluginprocessparent.h | 8 | 
2 files changed, 117 insertions, 13 deletions
| diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index e50db69190..eef22156bc 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -80,8 +80,29 @@ protected:  }; + +class LLPluginProcessCreationThread : public LLThread +{ +public: +    LLPluginProcessCreationThread(LLPluginProcessParent *parent) : +        LLThread("LLPluginProcessCreationThread", gAPRPoolp), +        pParent(parent) +    { +    } +protected: +    // Inherited from LLThread, should run once +    /*virtual*/ void run(void) +    { +        pParent->createPluginProcess(); +    } +private: +    LLPluginProcessParent *pParent; + +}; +  LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): -	mIncomingQueueMutex() +    mIncomingQueueMutex(), +    pProcessCreationThread(NULL)  {  	if(!sInstancesMutex)  	{ @@ -110,6 +131,18 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):  LLPluginProcessParent::~LLPluginProcessParent()  {  	LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; +    if (pProcessCreationThread) +    { +        if (!pProcessCreationThread->isStopped()) +        { +            // Shouldn't happen at this stage +            LL_WARNS("Plugin") << "Shutting down active pProcessCreationThread" << LL_ENDL; +            pProcessCreationThread->shutdown(); +            ms_sleep(20); +        } +        delete pProcessCreationThread; +        pProcessCreationThread = NULL; +    }  	// Destroy any remaining shared memory regions  	sharedMemoryRegionsType::iterator iter; @@ -160,6 +193,7 @@ void LLPluginProcessParent::shutdown()              && state != STATE_ERROR)          {              (*it).second->setState(STATE_GOODBYE); +            (*it).second->mOwner = NULL;          }          if (state != STATE_DONE)          { @@ -314,6 +348,35 @@ bool LLPluginProcessParent::accept()  	return result;	  } +bool LLPluginProcessParent::createPluginProcess() +{ +    if (!mProcess) +    { +        // Only argument to the launcher is the port number we're listening on +        mProcessParams.args.add(stringize(mBoundPort)); +        mProcess = LLProcess::create(mProcessParams); +        return mProcess != NULL; +    } + +    return false; +} + +void LLPluginProcessParent::clearProcessCreationThread() +{ +    if (pProcessCreationThread) +    { +        if (!pProcessCreationThread->isStopped()) +        { +            pProcessCreationThread->shutdown(); +        } +        else +        { +            delete pProcessCreationThread; +            pProcessCreationThread = NULL; +        } +    } +} +  void LLPluginProcessParent::idle(void)  {  	bool idle_again; @@ -321,8 +384,9 @@ void LLPluginProcessParent::idle(void)  	do  	{  		// process queued messages -		mIncomingQueueMutex.lock(); -		while(!mIncomingQueue.empty()) +        // Inside main thread, it is preferable not to block it on mutex. +		bool locked = mIncomingQueueMutex.trylock(); +		while(locked && !mIncomingQueue.empty())  		{  			LLPluginMessage message = mIncomingQueue.front();  			mIncomingQueue.pop(); @@ -330,10 +394,13 @@ void LLPluginProcessParent::idle(void)  			receiveMessage(message); -			mIncomingQueueMutex.lock(); +			locked = mIncomingQueueMutex.trylock();  		} -		mIncomingQueueMutex.unlock(); +        if (locked) +        { +            mIncomingQueueMutex.unlock(); +        }  		// Give time to network processing  		if(mMessagePipe) @@ -342,7 +409,10 @@ void LLPluginProcessParent::idle(void)  			mMessagePipe->pumpOutput();  			// Only do input processing here if this instance isn't in a pollset. -			if(!mPolledInput) +			// If viewer and plugin are both shutting down, don't process further +			// input, viewer won't be able to handle it. +			if(!mPolledInput +			   && !(mState >= STATE_GOODBYE && LLApp::isExiting()))  			{  				mMessagePipe->pumpInput();  			} @@ -469,14 +539,30 @@ void LLPluginProcessParent::idle(void)  			case STATE_LISTENING:  			    {  				    // Launch the plugin process. +                    if (mDebug && !pProcessCreationThread) +                    { +                        createPluginProcess(); +                        if (!mProcess) +                        { +                            errorState(); +                        } +                    } +                    else if (pProcessCreationThread == NULL) +                    { +                        // exe plugin process allocation can be hindered by a number +                        // of factors, don't hold whole viewer because of it, use thread +                        pProcessCreationThread = new LLPluginProcessCreationThread(this); +                        pProcessCreationThread->start(); +                    } +                    else if (!mProcess && pProcessCreationThread->isStopped()) +                    { +                        delete pProcessCreationThread; +                        pProcessCreationThread = NULL; +                        errorState(); +                    } + -				    // Only argument to the launcher is the port number we're listening on -				    mProcessParams.args.add(stringize(mBoundPort)); -				    if (! (mProcess = LLProcess::create(mProcessParams))) -				    { -					    errorState(); -				    } -				    else +				    if (mProcess)  				    {  					    if(mDebug)  					    { @@ -505,6 +591,15 @@ void LLPluginProcessParent::idle(void)  					    // This will allow us to time out if the process never starts.  					    mHeartbeat.start();  					    mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); + +                        // pProcessCreationThread should have stopped by this point, +                        // but check just in case it paused on statistics sync +                        if (pProcessCreationThread && pProcessCreationThread->isStopped()) +                        { +                            delete pProcessCreationThread; +                            pProcessCreationThread = NULL; +                        } +  					    setState(STATE_LAUNCHED);  				    }  			    } @@ -607,6 +702,7 @@ void LLPluginProcessParent::idle(void)  				killSockets();  				setState(STATE_DONE);                  dirtyPollSet(); +                clearProcessCreationThread();  			    break;  			case STATE_DONE: diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index df1630255c..1893c9e657 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -69,6 +69,11 @@ public:  			  const std::string &plugin_filename,   			  bool debug); +    // Creates a process +    // returns true if process already exists or if created, +    // false if failed to create +    bool createPluginProcess(); +  	void idle(void);  	// returns true if the plugin is on its way to steady state @@ -163,12 +168,15 @@ private:  	bool accept(); +    void clearProcessCreationThread(); +  	LLSocket::ptr_t mListenSocket;  	LLSocket::ptr_t mSocket;  	U32 mBoundPort;  	LLProcess::Params mProcessParams;  	LLProcessPtr mProcess; +	LLThread *pProcessCreationThread;  	std::string mPluginFile;  	std::string mPluginDir; | 
