diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-09-30 23:10:49 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-09-30 23:12:11 -0500 |
commit | 697d333afb6138647db665ab65f17c823d205b7c (patch) | |
tree | b4f85228063bb2a4b599578de182034bcba18e05 | |
parent | 7de892a51ca32774e86f60d575945871c643518d (diff) | |
download | tdemultimedia-697d333afb6138647db665ab65f17c823d205b7c.tar.gz tdemultimedia-697d333afb6138647db665ab65f17c823d205b7c.zip |
Fix threading deadlock between Xine and our X11 event processor
This relates to Bug 1905
-rw-r--r-- | xine_artsplugin/xinePlayObject_impl.cpp | 83 |
1 files changed, 45 insertions, 38 deletions
diff --git a/xine_artsplugin/xinePlayObject_impl.cpp b/xine_artsplugin/xinePlayObject_impl.cpp index d4681d59..4cb83e6f 100644 --- a/xine_artsplugin/xinePlayObject_impl.cpp +++ b/xine_artsplugin/xinePlayObject_impl.cpp @@ -683,47 +683,54 @@ void xinePlayObject_impl::resizeNotify() XFlush( display ); } +// FIXME +// Due to somewhat recent changes in XLib threading this had to be changed to a polling routine +// Specifically XNextEvent acquires a global XLib lock, preventing any other XLib methods (including those used in the Xine library) from executing +// Seems this is a known problem in other projects as well, with the only real option being a rewrite to use xcb natively (not sure if that is even possible here): +// http://mail-archives.apache.org/mod_mbox/harmony-dev/200905.mbox/%3C200905181317.n4IDHtGQ002008@d06av03.portsmouth.uk.ibm.com%3E void xinePlayObject_impl::eventLoop() { - XEvent event; - - do - { - XNextEvent( display, &event ); - - if (event.type == Expose && event.xexpose.count == 0 && - event.xexpose.window == visual.d) - { - pthread_mutex_lock( &mutex ); - - if (stream != 0) - { - xine_port_send_gui_data( vo_port, - XINE_GUI_SEND_EXPOSE_EVENT, - &event ); - } - else - { - clearWindow(); - } - pthread_mutex_unlock( &mutex ); + XEvent event; + bool eventReceived = false; + + do { + if (XPending( display )) { + XNextEvent( display, &event ); + eventReceived = true; + + if (event.type == Expose && event.xexpose.count == 0 && event.xexpose.window == visual.d) { + pthread_mutex_lock( &mutex ); + + if (stream != 0) { + xine_port_send_gui_data( vo_port, + XINE_GUI_SEND_EXPOSE_EVENT, + &event ); + } + else { + clearWindow(); + } + pthread_mutex_unlock( &mutex ); + } + else if (event.type == shmCompletionType) { + pthread_mutex_lock( &mutex ); + + if (stream != 0) { + xine_port_send_gui_data( vo_port, + XINE_GUI_SEND_COMPLETION_EVENT, + &event ); + } + pthread_mutex_unlock( &mutex ); + } + } + else { + usleep(10000); + eventReceived = false; + } } - else if (event.type == shmCompletionType) - { - pthread_mutex_lock( &mutex ); - - if (stream != 0) - { - xine_port_send_gui_data( vo_port, - XINE_GUI_SEND_COMPLETION_EVENT, - &event ); - } - pthread_mutex_unlock( &mutex ); - } - } - while (event.type != ClientMessage || - event.xclient.message_type != xcomAtomQuit || - event.xclient.window != xcomWindow); + while (!eventReceived || + event.type != ClientMessage || + event.xclient.message_type != xcomAtomQuit || + event.xclient.window != xcomWindow); } void xineVideoPlayObject_impl::x11WindowId( long window ) |