[wx-dev] Re: Re[2]: regression with event handing in wxBase (unix)

ATS asteinarson at gmail.com
Wed Mar 26 11:57:40 PDT 2008


> 
> On Wed, 26 Mar 2008 10:44:32 +0100 Lukasz Michalski <lm at ...> wrote:
> 
> LM> On Tuesday 25 March 2008, Lukasz Michalski wrote:
> LM> > Got next regression when stress-testing my program, this time the
> LM> > hard-to-debug one:
> LM> 
> LM> I found that this problem is related to AddPendingEvent call from child 
> LM> thread. More info and reproduction path: 
> LM> 

I can confirm this happening on trunk with both wxGTK and wxMSW. It seems
to happen in my setting also when another thread is posting events.


> 
>  I still don't really see how it happens however. A handler is only added
> to wxPendingEvents in wxEvtHandler::AddPendingEvent() and when this happens
> it does have some pending events in its m_pendingEvents list. And the
> events are removed from m_pendingEvents only from wxEvtHandler::
> ProcessPendingEvents() which also removes the handler from wxPendingEvents
> when m_pendingEvents becomes empty so how does it happen that it remains
> there during the next loop iteration? Do you understand it?

When I had this problem I spent some time looking at the logic around 
it. I found one minor locking glitch:

void wxEvtHandler::ProcessPendingEvents() {
    // ... 
    if ( m_pendingEvents->IsEmpty() )
        wxPendingEvents->DeleteObject(this);

should be something like: 

    if ( m_pendingEvents->IsEmpty() )
    {
#if wxUSE_THREADS
        if (wxPendingEventsLocker)
        {
            wxENTER_CRIT_SECT(*wxPendingEventsLocker);
            wxPendingEvents->DeleteObject(this);
            wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
        }
#else
        wxPendingEvents->DeleteObject(this);
#endif   // wxUSE_THREADS
    }
 

There are two sync objects involved, and the one specific to wxPendingEvents
list was not locked. I haven't had this assert for some time now, so 
maybe that was it.

It also seems to me that having two sync objects here is confusing. 
We have one sync object per event handler (protecting its queue) and
one global sync object (protecting wxPendingEvents list). I think 
just the global one would be enough. It's hard for me to see the need
for more fine grained locking than that. 

Regards
// ATS.






More information about the wx-dev mailing list