Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


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.

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.