views:

584

answers:

2

Hello,

I am using wxwidgets together with boost::thread. The Thread is a worker thread which sends some Events to the GUI:

Thread creation:

thrd = boost::thread(boost::bind(workerFunction,this));

Send Message to the GUI:

wxPostEvent(loWindow, event);
wxSafeYield();

Under Windows I don't see any problems, but when starting the application under Linux (Ubuntu 8.10), it stops with the following error message:

_XCBUnlockDisplay: Assertion `xcb_get_request_sent(dpy->xcb->connection) == dpy->request' failed.
Aborted

What am I missing? When the workerFunction is not started in a thread, it works without problems.

Regards, /mspoerr

+3  A: 

Don't call wxYield from a worker thread. Only do that from the GUI thread. Yield will process gui events, and is intended to be used if in some GUI event handler you do much of work and want to update other controls and process pending events in between. The Safe in wxSafeYield means that it disables GUI controls before it processes pending events first. That will protect you from such cases like entering the event handler you called wxYield from a second time, recursively. It doesn't mean that it is thread-safe, or something like that.

If you want to give the rest of the time slice your thread would have to other threads, call wx's wxThread::Yield or boost's this_thread::yield (depending on your thread class) instead.

Johannes Schaub - litb
Thank you for your answer, but the wxWidgets docu says:"Yields control to pending messages in the windowing system. This can be useful, for example, when a time-consuming process writes to a text window. Without an occasional yield, the text window will not be updated properly, and on systems with cooperative multitasking, such as Windows 3.1 other processes will not respond."And in my opinion this is what I need. When I don't use this function, also the Windows app crashes../mspoerr
mspoerr
The documentation you are quoting is talking about single threaded applications. If you want to yeild in a background thread, use an operating system function like Sleep(0) (defined in windows.h) or the boost equilivent.
Tom Leys
and whats the recommended way to implement this?
mspoerr
@mspoerr, the xcb error message seems to indicate mess-up with the GUI. note that you are not allowed to access *anything* of your GUI from a worker thread (like painting into a window, ...). do everything by sending events to the GUI and do GUI stuff there.
Johannes Schaub - litb
The only way I touch the GUI from the worker thread is by sending messages with wxPostEvent.I don't touch controls or windows directly.
mspoerr
Then i can't help you. Visit #wxwidets and #xcb or similar on freenode irc maybe they can help you. Wish you best lucks, maybe another guy in here has the answer. Usually, XCB is known to work well with threads, maybe you o rwx miss to call some xcb function (i remember that this problem existed with some KDE programs and xine).
Johannes Schaub - litb
ok - thank you.
mspoerr
A: 

The problem was with the data I sent - for complex data you need to use custom events. I now implemented a custom event and it works.

For more information please see http://wxforum.shadonet.com/viewtopic.php?t=24663

Thank you for your help!

/mspoerr

mspoerr
Yes, with that code you posted, the reason for the crash is obvious :)
Johannes Schaub - litb
Thanks for your exhilarant words ;)
mspoerr