Solarmutex Deadlock when Closing Calc which contains functions with XVolatileResult return values

anwen anwenfish at hotmail.com
Thu Aug 16 06:59:45 PDT 2012


Hi Stephan

Thank you for your effort to review my posts and give suggestions. Please
see my answers below.


Stephan Bergmann-2 wrote
> 
> So the situation is as follows:  When your notifyTermination() listener 
> is called (which apparently happens with the SolarMutex being locked), 
> you need to synchronously terminate and join your worker thread.  But at 
> that time your worker thread happens to be blocked waiting for the 
> SolarMutex, at some stack frame nested in a call to some modified() 
> (which is part of your code).  Right?  (Can you make available the 
> source code of your extension?)
> 
> I still see no true fix short of having the notifyTermination listeners 
> being fired without SolarMutex locked.
> 

There is a little difference: I used both queryTermination() and
notifyTermination(). Modified() may be blocked by queryTermination(), not
notifyTermination(). It happens by chance, not always. Then I do send a stop
message to the worker thread at notifyTermination().  Please see my
explanation in the code.

	void SAL_CALL BLP_VolatileResult::newValue()  // Here is the place calling
modified()
	{
		ResultEvent aEvent = getResult();
		
		for(XResultListenerVector::iterator iter = aListeners.begin(); iter !=
aListeners.end(); ++iter)
		{
			try
			{
				if (rtSessionStatus == RUNNING)  //rtSessionStaus is a global variable
				{
					(*iter)->modified(aEvent);
				}
			}
			catch (::com::sun::star::uno::Exception &)
			{
				iter = aListeners.erase(iter);
			}
		}
	}


// If modified() is called by the worker thread at the same time, the worker
thread is blocked forever; If not, everything goes through.
void SAL_CALL CalcTerminateListener::queryTermination(const
::com::sun::star::lang::EventObject& aEvent)
		throw( ::com::sun::star::frame::TerminationVetoException,
::com::sun::star::uno::RuntimeException ) 
{
	if (blp_conn->isRun()) //check if rtSessionStatus == RUNNING
	{
		blp_conn->prepareClose(); //set up rtSessionStatus = STOPPING
		throw ::com::sun::star::frame::TerminationVetoException();
	}
}  

void SAL_CALL CalcTerminateListener::notifyTermination(const
::com::sun::star::lang::EventObject& aEvent) 
	throw( ::com::sun::star::uno::RuntimeException )
{
	blp_conn->close(); //will send a stop message to the worker session which
connects to a outside server.
                                                 //it returns immediately.
If no block, the worker session will be ready for deletion later.
                                                 //If the worker session is
blocked by queryTermination() at modified(), 
                                                 //it will wait forever, 
deadlock. Maybe you can say it prepare to join and terminate the 
                                                 //worker thread
synchronously.
}

blp_conn::~blp_conn()
{
  if (d_session)
    deleting d_session;   //d_session is in charge of the worker thread. If
the worker thread is blocked at 
                                              //queryTermination() with
modified(), deadlock happens. Maybe you can say this step tries 
                                              //to join and terminate the
worker thread synchronously.
}



> So, you manually need to click the 'X' to close the LibreOffice window 
> twice?
> 
> And where do you call the code to terminate and join your worker thread 
> now?  (Or do you not call such code at all, and things appear to work by 
> chance, due to changes in timing?)
> 
> Stephan
> 

Yes, I do it twice. The first time, it calls queryTermination(), sets up
rtSessionStatus, and then is vetoed. Then I click x again. It calls
queryTermination, then notifyTermination() where I try to stop the worker
thread, and other destruction procedures where I try to join and terminate
the worker thread. 

I am suggested to create a new thread at queryTermination() along with
changing rtSessionStatus. This new thread will wait for a while and call
XDesktop.terminate(), just a simulation of the second click. Is it possible
to create such a new thread within LibreOffice extension?

Thank you.

Wendi




--
View this message in context: http://nabble.documentfoundation.org/Solarmutex-Deadlock-when-Closing-Calc-which-contains-functions-with-XVolatileResult-return-values-tp3998056p4001815.html
Sent from the Dev mailing list archive at Nabble.com.


More information about the LibreOffice mailing list