There was a race when closing a window.
It was possible to call set_done() on window _before_ event_thread is created, 
which caused non-delivery of the window close call.

I've reproduce this regularely when creating toc files for really really short 
mpegs...

This fix does the trick as it should be done. set_done() always puts message 
into queue, even when event_thread is not created yet. event_thread stopping is 
done by setting done=1 on it and sending itself a dummy message - all this in 
the destructor. 


bye
andraz
diff -ru --exclude-from exclude hvirtual-svn/guicast/bcwindowbase.C hvirtual-2.1/guicast/bcwindowbase.C
--- hvirtual-svn/guicast/bcwindowbase.C	2006-10-14 00:52:42.000000000 +0200
+++ hvirtual-2.1/guicast/bcwindowbase.C	2006-10-14 17:41:15.000000000 +0200
@@ -2677,7 +2677,6 @@
 	if(window_type != MAIN_WINDOW)
 		top_level->set_done(return_value);
 	else
-	if(event_thread)
 	{
 		XEvent *event = new XEvent;
 		XClientMessageEvent *ptr = (XClientMessageEvent*)event;
@@ -2691,15 +2690,10 @@
 // asynchronous with XNextEvent.
 // This causes BC_WindowEvents to forward a copy of the event to run_window where 
 // it is deleted.
-		event_thread->done = 1;
-		XSendEvent(display, 
-			win, 
-			0, 
-			0, 
-			event);
-		flush();
+
+// Deletion of event_thread is done at the end of BC_WindowBase::run_window() - by calling the destructor
 		put_event(event);
-	}
+	} 
 }
 
 int BC_WindowBase::get_w()
diff -ru --exclude-from exclude hvirtual-svn/guicast/bcwindowevents.C hvirtual-2.1/guicast/bcwindowevents.C
--- hvirtual-svn/guicast/bcwindowevents.C	2006-10-12 12:08:14.000000000 +0200
+++ hvirtual-2.1/guicast/bcwindowevents.C	2006-10-14 17:38:18.000000000 +0200
@@ -10,7 +10,19 @@
 
 BC_WindowEvents::~BC_WindowEvents()
 {
+// First set done, then send dummy event through XSendEvent to unlock the loop in ::run()
 	done = 1;
+	XEvent event;
+	XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
+	event.type = ClientMessage;
+	ptr->message_type = XInternAtom(window->display, "DUMMY_XATOM", False);
+	ptr->format = 32;
+	XSendEvent(window->display, 
+		window->win, 
+		0, 
+		0, 
+		&event);
+	window->flush();
 	Thread::join();
 }
 

Reply via email to