DocumentEventListener problem

Piet van Oostrum piet at vanoostrum.org
Wed Apr 15 05:18:23 PDT 2015


Stephan Bergmann wrote:

 > There's nothing special here.  LO's main thread 1 in 
 > SfxBaseModel::postEvent_Impl (frame 19) is illegally issuing 
 > css.document.XDocumentEventListener::documentEventOccured calls with the 
 > solar mutex locked.  The python process, while synchronously executing 
 > that documentEventOccured call, first issues a bunch of asynchronous 
 > release requests and then a synchronous 
 > css.document.XDocumentEventBroadcaster::addDocumentEventListener 
 > request.  One of the asyncronous release requests, executed on LO's 
 > thread 2, blocks waiting on the solar mutex.  And on the LO side, the 
 > incoming synchronous addDocumentEventListener request blocks waiting on 
 > the preceding asynchronous release requests to finish (which is how 
 > synchronous and asynchronous UNO requests work).

Yes, having the solar mutex locked while a listener is called looks like an extremely bad idea. The listener take a long time, it may do all kinds of things that may also require the mutex, like we see here with the destructors. Or it may even spark other listeners. I read somewhere that the solar mutex is for protecting the access to VCL, but it seems to me that it is also used for other purposes, is that right?

Anyway, this makes it almost impossible to use listeners across the UNO bridge. When I run my code as a macro inside LO there is no problem.

When I prevent the releases to happen then the listener also works without problem, but of course this is very fragile. I do this by collecting the para's in a list so that they will not be deleted. If I do this then the listener runs to the end, printing all the paragraphs and then LO hangs. If I make this list global and also parenum, so that won't be deleted at the end of the listener, then LO stays alive. I can then manually delete these after the listener has finished and there is no problem then.

See the modified code:

def showportions(doc):
    if doc.supportsService("com.sun.star.text.TextDocument"):
        global parenum
        parenum = doc.Text.createEnumeration()
        global paras
        paras = []
        while parenum.hasMoreElements():
            para = parenum.nextElement()
            paras.append(para)
            print("get para: {}".format(para.String))


-- 
Piet van Oostrum <piet at vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]


More information about the LibreOffice mailing list