summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-09-30 23:10:49 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-09-30 23:12:11 -0500
commit697d333afb6138647db665ab65f17c823d205b7c (patch)
treeb4f85228063bb2a4b599578de182034bcba18e05
parent7de892a51ca32774e86f60d575945871c643518d (diff)
downloadtdemultimedia-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.cpp83
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 )