currently there was a problem where thread was deleted within itself, so when 
Thread::entrypoint was being finished, it used variabiles of the thread that 
was already deleted, which is naturally problematic, since they could take any 
value...

The problem is quite hard to understand (and was hard to debug), but is most 
clearly illustrated by valgrind data on ChromaKey plugin:


==11903== Invalid read of size 4
==11903==    at 0x46B4001: Thread::entrypoint(void*) (in 
/usr/lib/libguicast.so.1.0.0)
==11903==    by 0x4BDBE5F: start_thread (in 
/lib/tls/i686/cmov/libpthread-2.3.6.so)
==11903==    by 0x4DCC8ED: clone (in /lib/tls/i686/cmov/libc-2.3.6.so)
==11903==  Address 0x52D7DC8 is 16 bytes inside a block of size 48 free'd
==11903==    at 0x401D304: operator delete(void*) (vg_replace_malloc.c:246)
==11903==    by 0x7976F40: ChromaKeyThread::~ChromaKeyThread() (chromakey.C:300)
==11903==    by 0x79797D7: ChromaKey::~ChromaKey() (chromakey.C:553)
==11903==    by 0x82B797F: PluginServer::close_plugin() (pluginserver.C:303)
==11903==    by 0x82B79BF: PluginServer::~PluginServer() (pluginserver.C:98)
==11903==    by 0x8241200: MWindow::hide_plugin(Plugin*, int) (mwindow.C:1511)
==11903==    by 0x82B9990: PluginServer::client_side_close() 
(pluginserver.C:318)
==11903==    by 0x82B1058: PluginClient::client_side_close() 
(pluginclient.C:176)
==11903==    by 0x797703A: ChromaKeyThread::run() (chromakey.C:316)
==11903==    by 0x46B3FE4: Thread::entrypoint(void*) (in 
/usr/lib/libguicast.so.1.0.0)
==11903==    by 0x4BDBE5F: start_thread (in 
/lib/tls/i686/cmov/libpthread-2.3.6.so)
==11903==    by 0x4DCC8ED: clone (in /lib/tls/i686/cmov/libc-2.3.6.so)



So, inside 
==11903==    by 0x797703A: ChromaKeyThread::run() (chromakey.C:316)
the destructor for itself:
==11903==    by 0x7976F40: ChromaKeyThread::~ChromaKeyThread() (chromakey.C:300)
was being called... which is obviously a bug and recepie for trobule
No matter what ::run does, it ends at the end of Thread::entrypoint where 
another deletion may happen if some other thread races to take the deleted 
memory and maybe sets autodelete variabile to nonzero...



This patch fixes this bug by using autodelete property on ChromaKeyThread, and 
lets it run out by itself... 

Even though it looks sketchy at first, it is not, since it also uses join() 
which waits only when it is not called on the thread itself. 



bye
andraz
--- hvirtual-cvs/cinelerra/pluginclient.h	2006-05-19 09:52:50.000000000 +0200
+++ hvirtual-2/cinelerra/pluginclient.h	2006-05-31 20:41:50.000000000 +0200
@@ -62,16 +62,14 @@
 	void run(); \
 	window_class *window; \
 	plugin_class *plugin; \
-	Condition *completion; \
 };
 
 
 #define PLUGIN_THREAD_OBJECT(plugin_class, thread_class, window_class) \
 thread_class::thread_class(plugin_class *plugin) \
- : Thread(0, 0, 0) \
+ : Thread(0, 0, 1) \
 { \
 	this->plugin = plugin; \
-	completion = new Condition(0, "thread_class::completion"); \
 } \
  \
 thread_class::~thread_class() \
@@ -90,7 +88,6 @@
 /* Only set it here so tracking doesn't update it until everything is created. */ \
  	plugin->thread = this; \
 	int result = window->run_window(); \
-	completion->unlock(); \
 /* This is needed when the GUI is closed from itself */ \
 	if(result) plugin->client_side_close(); \
 }
@@ -118,11 +115,12 @@
 	if(thread) \
 	{ \
 /* This is needed when the GUI is closed from elsewhere than itself */ \
+/* Since we now use autodelete, this is all that has to be done, thread will take care of itself ... */ \
+/* Thread join will wait if this was not called from the thread itself or go on if it was */ \
 		thread->window->lock_window("PLUGIN_DESTRUCTOR_MACRO"); \
 		thread->window->set_done(0); \
 		thread->window->unlock_window(); \
-		thread->completion->lock("PLUGIN_DESTRUCTOR_MACRO"); \
-		delete thread; \
+		thread->join(); \
 	} \
  \
  \

Reply via email to