diff -u base/guicast/bcrepeater.C hvirtual-1.1.6/guicast/bcrepeater.C
--- base/guicast/bcrepeater.C	2003-07-23 20:48:34.000000000 +0200
+++ hvirtual-1.1.6/guicast/bcrepeater.C	2003-07-23 22:18:44.000000000 +0200
@@ -10,19 +10,18 @@
 	this->delay = delay;
 	this->top_level = top_level;
 
-	pause_lock.lock();
-	startup_lock.lock();
+//	pause_lock.lock(); // locked by default
 	start();
 // This is important.  It doesn't unblock until the thread is running.
-	startup_lock.lock();
-	startup_lock.unlock();
+	startup_signal.wait_first_signal();
 }
 
 BC_Repeater::~BC_Repeater()
 {
 	interrupted = 1;
-	pause_lock.unlock();
-	repeat_lock.unlock();
+//	pause_lock.unlock();
+	pause_signal.signal();
+	repeat_signal.broadcast();
 	Thread::end();
 	Thread::join();
 }
@@ -34,7 +33,8 @@
 	if(repeating == 1)
 	{
 // Resume the loop
-		pause_lock.unlock();
+//		pause_lock.unlock();
+		pause_signal.signal();
 	}
 	return 0;
 }
@@ -46,7 +46,9 @@
 	{
 		repeating--;
 // Pause the loop
-		if(repeating == 0) pause_lock.lock();
+		if(repeating == 0) 
+			pause_signal.wait_one_signal();
+// pause_lock.lock();
 	}
 	return 0;
 }
@@ -55,8 +57,8 @@
 {
 	next_delay = delay;
 	Thread::disable_cancel();
-	startup_lock.unlock();
-
+	startup_signal.broadcast();
+	repeat_signal.broadcast();
 	while(!interrupted)
 	{
 		Thread::enable_cancel();
@@ -70,8 +72,10 @@
 //		if(repeating <= 0) continue;
 
 // Test for pause
-		pause_lock.lock();
-		pause_lock.unlock();
+//		pause_lock.lock();
+//		pause_lock.unlock();
+		pause_signal.wait_one_signal();
+		pause_signal.signal();
 		timer.update();
 
 // Test exit conditions
@@ -79,17 +83,17 @@
 		if(repeating <= 0) continue;
 
 // Wait for existing signal to be processed before sending a new one
-		repeat_lock.lock();
+		repeat_signal.wait_one_signal();
 
 // Test exit conditions
 		if(interrupted)
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			return;
 		}
 		if(repeating <= 0)
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			continue;
 		}
 
@@ -99,13 +103,13 @@
 // Test exit conditions
 		if(interrupted)
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			top_level->unlock_window();
 			return;
 		}
 		if(repeating <= 0)
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			top_level->unlock_window();
 			continue;
 		}
@@ -119,12 +123,12 @@
 // Test exit conditions
 		if(interrupted) 
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			return;
 		}
 		if(repeating <= 0)
 		{
-			repeat_lock.unlock();
+			repeat_signal.signal();
 			continue;
 		}
 	}
diff -u base/guicast/bcrepeater.h hvirtual-1.1.6/guicast/bcrepeater.h
--- base/guicast/bcrepeater.h	2003-07-23 20:48:34.000000000 +0200
+++ hvirtual-1.1.6/guicast/bcrepeater.h	2003-07-23 22:18:46.000000000 +0200
@@ -4,6 +4,7 @@
 #include "bcrepeater.inc"
 #include "bcwindowbase.inc"
 #include "mutex.h"
+#include "condvar.h"
 #include "thread.h"
 #include "timer.h"
 
@@ -22,15 +23,15 @@
 	int repeating;
 	int interrupted;
 // Prevent new signal until existing event is processed
-	Mutex repeat_lock;
+	CondVar repeat_signal;
 
 private:
 	Timer timer;
 	BC_WindowBase *top_level;
 // Delay corrected for the time the last repeat took
 	long next_delay;
-	Mutex pause_lock;
-	Mutex startup_lock;
+	CondVar pause_signal;
+	CondVar startup_signal;
 };
 
 
diff -u base/guicast/bcwindowbase.C hvirtual-1.1.6/guicast/bcwindowbase.C
--- base/guicast/bcwindowbase.C	2003-07-23 20:49:11.000000000 +0200
+++ hvirtual-1.1.6/guicast/bcwindowbase.C	2003-07-23 22:18:44.000000000 +0200
@@ -17,6 +17,7 @@
 #include "keys.h"
 #include "sizes.h"
 #include "vframe.h"
+#include "condvar.h"
 
 #ifdef HAVE_GL
 #include <GL/gl.h>
@@ -1077,7 +1078,7 @@
 		{
 			if(repeaters.values[i]->delay == duration)
 			{
-				repeaters.values[i]->repeat_lock.unlock();
+				repeaters.values[i]->repeat_signal.broadcast();
 			}
 		}
 	}
diff -u base/guicast/mutex.C hvirtual-1.1.6/guicast/mutex.C
--- base/guicast/mutex.C	2003-07-23 20:49:27.000000000 +0200
+++ hvirtual-1.1.6/guicast/mutex.C	2003-07-23 22:18:44.000000000 +0200
@@ -1,4 +1,5 @@
 #include "mutex.h"
+#include "thread.h"
 
 Mutex::Mutex()
 {
@@ -17,13 +18,23 @@
 	
 int Mutex::lock()
 {
-	if(pthread_mutex_lock(&mutex)) perror("Mutex::lock");
+	if(pthread_mutex_lock(&mutex)) {
+		perror("Mutex::lock");
+#ifdef DEBUG
+		printf("Thread id: %i,  name: %s\n", pthread_self(), get_thread_name());
+#endif
+	}
 	return 0;
 }
 
 int Mutex::unlock()
 {
-	if(pthread_mutex_unlock(&mutex)) perror("Mutex::unlock");
+	if(pthread_mutex_unlock(&mutex)) {
+		perror("Mutex::unlock");
+#ifdef DEBUG
+		printf("Thread id: %i,  name: %s\n", pthread_self(), get_thread_name());
+#endif
+	}
 	return 0;
 }
 
diff -u base/guicast/thread.C hvirtual-1.1.6/guicast/thread.C
--- base/guicast/thread.C	2003-07-23 20:49:36.000000000 +0200
+++ hvirtual-1.1.6/guicast/thread.C	2003-07-29 02:02:39.000000000 +0200
@@ -4,6 +4,54 @@
 #include <unistd.h>
 #include "thread.h"
 
+#ifdef DEBUG
+
+#include <typeinfo>
+#include <string.h>
+#include "mutex.h"
+
+	char thread_names[TMAX][64];
+	char not_found_name[]="Unknown thread or thread info array full";
+	int thread_ids[TMAX];
+	int thread_count = 0;
+	Mutex tn_mutex;
+	char *get_thread_name()	
+	{
+		tn_mutex.lock();
+		int tid=pthread_self();
+		for (int i=0; i<thread_count; i++)
+			if (thread_ids[i]==tid)
+			{
+				tn_mutex.unlock();
+				return(thread_names[i]);
+			}
+		tn_mutex.unlock();
+		return (not_found_name);
+	}
+	
+//void Thread::afterrun() {
+#define thread_afterrun \
+	{ \
+	tn_mutex.lock(); \
+	 \
+	int tid= pthread_self(); \
+	if (thread_count == 1) \
+		thread_count = 0; \
+	else { \
+		for (int i=0; i<thread_count; i++) \
+		{	\
+			if (thread_ids[i]== tid) { \
+				thread_ids[i]= thread_ids[thread_count-1]; \
+				strcpy(thread_names[i],thread_names[thread_count-1]); \
+ 				break; \
+			} \
+		} \
+		thread_count--; \
+	} \
+	tn_mutex.unlock(); \
+}
+
+#endif
 
 Thread::Thread(int synchronous, int realtime, int autodelete)
 {
@@ -26,16 +74,41 @@
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
 // Disable cancellation by default.
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
-	
+
+#ifdef DEBUG
+	thread->prerun();
+#endif	
 
 	thread->run();
 
+#ifdef DEBUG
+	thread_afterrun;
+#endif	
+
 	thread->thread_running = 0;
 
 	if(thread->autodelete && !thread->synchronous) delete thread;
 	return NULL;
 }
 
+#ifdef DEBUG
+void Thread::prerun() {
+	tn_mutex.lock();
+	if (thread_count < TMAX) {
+		thread_ids[thread_count] = pthread_self(); 
+		strcpy (thread_names[thread_count],typeid(*this).name() ); 
+		thread_count ++;
+	} else 
+	{
+		printf("too many threads created, thread debugging has given up\n");
+	}
+	tn_mutex.unlock();
+
+}
+
+
+#endif
+
 void Thread::start()
 {
 	pthread_attr_t  attr;
diff -u base/guicast/thread.h hvirtual-1.1.6/guicast/thread.h
--- base/guicast/thread.h	2003-07-23 20:49:36.000000000 +0200
+++ hvirtual-1.1.6/guicast/thread.h	2003-07-23 22:18:47.000000000 +0200
@@ -8,6 +8,18 @@
 // If it's synchronous the deletion occurs in join().
 // If it's asynchronous the deletion occurs in entrypoint.
 
+#define DEBUG
+
+#ifdef DEBUG
+	#define TMAX 255
+	extern char thread_names[TMAX][64];
+	extern int thread_ids[TMAX];
+	extern int thread_count;
+
+	char *get_thread_name(); // function that returns a pointer to the name of the object of the current thread
+
+#endif
+
 
 class Thread
 {
@@ -15,6 +27,9 @@
 	static void* entrypoint(void *parameters);
 protected:
 	virtual void run() = 0;
+#ifdef DEBUG
+	virtual void prerun();
+#endif
 public:
 	Thread(int synchronous = 0, int realtime = 0, int autodelete = 0);
 	virtual ~Thread();
diff -u base/cinelerra/arender.C hvirtual-1.1.6/cinelerra/arender.C
--- base/cinelerra/arender.C	2003-07-23 20:38:09.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/arender.C	2003-07-23 22:19:48.000000000 +0200
@@ -284,7 +284,7 @@
 //printf("ARender::run 1\n");
 
 //sleep(1);
-	start_lock.unlock();
+	start_signal.signal();
 
 //printf("ARender::run 2 %d %d %d\n", done, interrupt, last_playback);
 	while(!done && !interrupt && !last_playback)
diff -u base/cinelerra/commonrender.C hvirtual-1.1.6/cinelerra/commonrender.C
--- base/cinelerra/commonrender.C	2003-07-23 20:39:33.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/commonrender.C	2003-07-23 22:19:48.000000000 +0200
@@ -161,10 +161,10 @@
 {
 	if(renderengine->command->realtime)
 	{
-		start_lock.lock();
+		start_signal.set_signalhistory(0);
 		Thread::start();
-		start_lock.lock();
-		start_lock.unlock();
+		start_signal.wait_first_signal();
+		start_signal.signal();
 	}
 }
 
@@ -267,7 +267,7 @@
 
 void CommonRender::run()
 {
-	start_lock.unlock();
+	start_signal.signal();
 }
 
 
diff -u base/cinelerra/commonrender.h hvirtual-1.1.6/cinelerra/commonrender.h
--- base/cinelerra/commonrender.h	2003-07-23 20:39:34.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/commonrender.h	2003-07-23 22:19:51.000000000 +0200
@@ -5,6 +5,7 @@
 #include "virtualconsole.inc"
 #include "module.inc"
 #include "mutex.h"
+#include "condvar.h"
 #include "mwindow.inc"
 #include "renderengine.inc"
 #include "thread.h"
@@ -39,7 +40,7 @@
 	VirtualConsole *vconsole;
 // Native units position in project used for all functions
 	long current_position;       
-	Mutex start_lock;
+	CondVar start_signal;
 // flag for normally completed playback
 	int done;       
 // Flag for interrupted playback
diff -u base/cinelerra/cwindowtool.C hvirtual-1.1.6/cinelerra/cwindowtool.C
--- base/cinelerra/cwindowtool.C	2003-07-23 20:39:57.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/cwindowtool.C	2003-07-23 22:19:48.000000000 +0200
@@ -31,19 +31,25 @@
 	done = 0;
 	current_tool = CWINDOW_NONE;
 	set_synchronous(1);
-	input_lock = new Mutex;
-	input_lock->lock();
-	output_lock = new Mutex;
+//	input_lock = new Mutex;
+//	input_lock->lock();
+	dataready_signal = new CondVar;
+//	output_lock = new Mutex;
+	accepting_signal = new CondVar;
+	accepting_signal->set_signalhistory(3);
 }
 
 CWindowTool::~CWindowTool()
 {
 	done = 1;
 	stop_tool();
-	input_lock->unlock();
+//	input_lock->unlock();
+	dataready_signal->signal();
 	Thread::join();
-	delete input_lock;
-	delete output_lock;
+//	delete input_lock;
+//	delete output_lock;
+	delete dataready_signal;
+	delete accepting_signal;
 }
 
 void CWindowTool::start_tool(int operation)
@@ -81,10 +87,12 @@
 		if(!result)
 		{
 			stop_tool();
-			output_lock->lock();
+//			output_lock->lock();
+			accepting_signal->wait_one_signal();
 			this->tool_gui = new_gui;
 			tool_gui->create_objects();
-			input_lock->unlock();
+//			input_lock->unlock();
+			dataready_signal->signal();
 		}
 //printf("CWindowTool::start_tool 1\n");
 	}
@@ -115,14 +123,16 @@
 {
 	while(!done)
 	{
-		input_lock->lock();
+//		input_lock->lock();
+		dataready_signal->wait_one_signal();
 		if(!done)
 		{
 			tool_gui->run_window();
 			delete tool_gui;
 			tool_gui = 0;
 		}
-		output_lock->unlock();
+//		output_lock->unlock();
+		accepting_signal->signal();
 	}
 }
 
diff -u base/cinelerra/cwindowtool.h hvirtual-1.1.6/cinelerra/cwindowtool.h
--- base/cinelerra/cwindowtool.h	2003-07-23 20:39:58.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/cwindowtool.h	2003-07-23 22:19:51.000000000 +0200
@@ -6,6 +6,7 @@
 #include "guicast.h"
 #include "maskauto.inc"
 #include "mwindow.inc"
+#include "condvar.h"
 
 
 class CWindowToolGUI;
@@ -28,8 +29,8 @@
 	CWindowToolGUI *tool_gui;
 	int done;
 	int current_tool;
-	Mutex *input_lock, *output_lock;
-	
+//	Mutex *input_lock, *output_lock;
+	CondVar *dataready_signal, *accepting_signal;	
 };
 
 class CWindowToolGUI : public BC_Window
diff -u base/cinelerra/loadbalance.C hvirtual-1.1.6/cinelerra/loadbalance.C
--- base/cinelerra/loadbalance.C	2003-07-23 20:41:52.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/loadbalance.C	2003-07-23 22:19:48.000000000 +0200
@@ -5,7 +5,7 @@
 
 LoadPackage::LoadPackage()
 {
-	completion_lock.lock();
+//	completion_lock.lock();
 }
 LoadPackage::~LoadPackage()
 {
@@ -26,14 +26,15 @@
 	this->server = server;
 	done = 0;
 	package_number = 0;
-	input_lock.lock();
-	completion_lock.lock();
+//	input_lock.lock();
+//	completion_lock.lock();
 }
 
 LoadClient::~LoadClient()
 {
 	done = 1;
-	input_lock.unlock();
+//	input_lock.unlock();
+	dataready_signal.signal();
 	Thread::join();
 }
 
@@ -47,8 +48,8 @@
 {
 	while(!done)
 	{
-		input_lock.lock();
-
+//		input_lock.lock();
+		dataready_signal.wait_one_signal();
 		if(!done)
 		{
 // Read packet
@@ -61,15 +62,18 @@
 				package_number = server->current_package;
 				package = server->packages[server->current_package++];
 				server->client_lock.unlock();
-				input_lock.unlock();
-
+//				input_lock.unlock();
+				dataready_signal.signal();
+		
 				process_package(package);
 
-				package->completion_lock.unlock();
+//				package->completion_lock.unlock();
+				package->completion_signal.signal();
 			}
 			else
 			{
-				completion_lock.unlock();
+//				completion_lock.unlock();
+				completion_signal.signal();
 				server->client_lock.unlock();
 			}
 		}
@@ -185,19 +189,22 @@
 // Start all clients
 	for(int i = 0; i < total_clients; i++)
 	{
-		clients[i]->input_lock.unlock();
+//		clients[i]->input_lock.unlock();
+		clients[i]->dataready_signal.signal();
 	}
 	
 // Wait for packages to get finished
 	for(int i = 0; i < total_packages; i++)
 	{
-		packages[i]->completion_lock.lock();
+//		packages[i]->completion_lock.lock();
+		packages[i]->completion_signal.wait_one_signal();
 	}
 
 // Wait for clients to finish before allowing changes to packages
 	for(int i = 0; i < total_clients; i++)
 	{
-		clients[i]->completion_lock.lock();
+//		clients[i]->completion_lock.lock();
+		clients[i]->completion_signal.wait_one_signal();
 	}
 }
 
diff -u base/cinelerra/loadbalance.h hvirtual-1.1.6/cinelerra/loadbalance.h
--- base/cinelerra/loadbalance.h	2003-07-23 20:41:52.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/loadbalance.h	2003-07-23 22:19:51.000000000 +0200
@@ -3,6 +3,7 @@
 
 #include "mutex.h"
 #include "thread.h"
+#include "condvar.h"
 
 
 
@@ -21,7 +22,7 @@
 	LoadPackage();
 	virtual ~LoadPackage();
 	
-	Mutex completion_lock;
+	CondVar completion_signal;
 };
 
 
@@ -37,7 +38,7 @@
 
 	int done;
 	int package_number;
-	Mutex input_lock, completion_lock;
+	CondVar dataready_signal, completion_signal;
 	LoadServer *server;
 };
 
diff -u base/cinelerra/mainindexes.C hvirtual-1.1.6/cinelerra/mainindexes.C
--- base/cinelerra/mainindexes.C	2003-07-23 20:41:59.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/mainindexes.C	2003-07-23 22:19:48.000000000 +0200
@@ -9,6 +9,7 @@
 #include "mainprogress.h"
 #include "mwindow.h"
 #include "mwindowgui.h"
+#include "condvar.h"
 
 #include <string.h>
 
@@ -20,6 +21,7 @@
 	interrupt_flag = 0;
 	done = 0;
 	indexfile = new IndexFile(mwindow);
+	interrupt_signal.signal();
 }
 
 MainIndexes::~MainIndexes()
@@ -62,7 +64,9 @@
 
 void MainIndexes::start_loop()
 {
-	input_lock.lock();
+//	input_lock.lock();
+//	input_signal is locked by default
+	input_signal.set_signalhistory(0);
 	interrupt_flag = 0;
 	start();
 }
@@ -70,7 +74,8 @@
 void MainIndexes::stop_loop()
 {
 	interrupt_flag = 1;
-	input_lock.unlock();
+//	input_lock.unlock();
+	input_signal.signal();
 	Thread::join();
 }
 
@@ -82,7 +87,8 @@
 // Locked up when indexes were already being built and an asset was 
 // pasted.
 //	interrupt_lock.lock();
-	input_lock.unlock();
+//	input_lock.unlock();
+	input_signal.signal();
 }
 
 void MainIndexes::interrupt_build()
@@ -91,9 +97,9 @@
 	interrupt_flag = 1;
 	indexfile->interrupt_index();
 //printf("MainIndexes::interrupt_build 2\n");
-	interrupt_lock.lock();
+	interrupt_signal.wait_one_signal();
 //printf("MainIndexes::interrupt_build 3\n");
-	interrupt_lock.unlock();
+	interrupt_signal.signal();
 //printf("MainIndexes::interrupt_build 4\n");
 }
 
@@ -117,7 +123,8 @@
 	while(!done)
 	{
 // Wait for new assets to be released
-		input_lock.lock();
+//		input_lock.lock();
+		input_signal.wait_one_signal();
 		if(done) return;
 
 //printf("MainIndexes::run 1 %d\n", next_assets.total);
@@ -198,7 +205,7 @@
 
 //printf("MainIndexes::run 11\n");
 
-		interrupt_lock.unlock();
+		interrupt_signal.signal();
 	}
 }
 
diff -u base/cinelerra/mainindexes.h hvirtual-1.1.6/cinelerra/mainindexes.h
--- base/cinelerra/mainindexes.h	2003-07-23 20:41:59.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/mainindexes.h	2003-07-23 22:19:51.000000000 +0200
@@ -4,9 +4,11 @@
 #include "assets.inc"
 #include "indexfile.inc"
 #include "mutex.h"
+#include "condvar.h"
 #include "mwindow.inc"
 #include "thread.h"
 
+
 // Runs in a loop, creating new index files as needed
 
 class MainIndexes : public Thread
@@ -31,9 +33,9 @@
 	int interrupt_flag;                 // Build process interrupted by user
 	int done;                           // Program quit
 	MWindow *mwindow;
-	Mutex input_lock;                   // Lock until new data is to be indexed
+	CondVar input_signal;                   // Lock until new data is to be indexed
 	Mutex next_lock;                    // Lock changes to next assets
-	Mutex interrupt_lock;               // Force blocking until thread is finished
+	CondVar interrupt_signal;               // Force blocking until thread is finished
 	IndexFile *indexfile;
 };
 
diff -u base/cinelerra/maskengine.C hvirtual-1.1.6/cinelerra/maskengine.C
--- base/cinelerra/maskengine.C	2003-07-23 20:42:16.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/maskengine.C	2003-07-23 22:19:48.000000000 +0200
@@ -11,12 +11,15 @@
 
 MaskPackage::MaskPackage()
 {
-	apply_mutex = new Mutex;
+//	apply_mutex = new Mutex;
+	apply_condvar = new CondVar;
+	apply_condvar->set_signalhistory(3);
 }
 
 MaskPackage::~MaskPackage()
 {
-	delete apply_mutex;
+//	delete apply_mutex;
+	delete apply_condvar;
 }
 
 
@@ -595,7 +598,8 @@
 				i++)
 			{
 				MaskPackage *package = (MaskPackage*)engine->get_package(i);
-				package->apply_mutex->unlock();
+//				package->apply_mutex->unlock();
+				package->apply_condvar->signal();
 			}
 		}
 
@@ -606,8 +610,11 @@
 	if(ptr->part == APPLY_PART)
 	{
 //printf("MaskUnit::process_package 2.1\n");
-		ptr->apply_mutex->lock();
-		ptr->apply_mutex->unlock();
+//		ptr->apply_mutex->lock();
+//		ptr->apply_mutex->unlock();
+		ptr->apply_condvar->wait_one_signal();
+		ptr->apply_condvar->signal();
+		
 //printf("MaskUnit::process_package 2.2\n");
 
 		if(engine->recalculate)
@@ -949,7 +956,8 @@
 			part2->row2 = part1->row2 = output->get_h();
 		}
 
-		part2->apply_mutex->lock();
+//		part2->apply_mutex->lock();
+		part2->apply_condvar->wait_one_signal();
 
 		part1->part = RECALCULATE_PART;
 		part2->part = APPLY_PART;
Only in base/cinelerra/: maskengine.C~
diff -u base/cinelerra/maskengine.h hvirtual-1.1.6/cinelerra/maskengine.h
--- base/cinelerra/maskengine.h	2003-07-23 20:42:16.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/maskengine.h	2003-07-23 22:19:51.000000000 +0200
@@ -27,7 +27,7 @@
 
 	int row1, row2;
 	int part;
-	Mutex *apply_mutex;
+	CondVar *apply_condvar;
 };
 
 class MaskUnit : public LoadClient
diff -u base/cinelerra/playbackengine.C hvirtual-1.1.6/cinelerra/playbackengine.C
--- base/cinelerra/playbackengine.C	2003-07-23 20:43:28.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/playbackengine.C	2003-07-23 22:19:48.000000000 +0200
@@ -30,6 +30,7 @@
 	audio_cache = 0;
 	video_cache = 0;
 	last_command = STOP;
+	pause_signal.signal();
 	Thread::set_synchronous(1);
 }
 
@@ -71,13 +72,10 @@
 	*preferences = *mwindow->preferences;
 
 	done = 0;
-	start_lock.lock();
 //printf("PlaybackEngine::create_objects 1\n");
 	Thread::start();
 //printf("PlaybackEngine::create_objects 1\n");
-	start_lock.lock();
-//printf("PlaybackEngine::create_objects 1\n");
-	start_lock.unlock();
+	start_signal.wait_first_signal();
 //printf("PlaybackEngine::create_objects 1\n");
 	return result;
 }
@@ -208,7 +206,7 @@
 		render_engines.values[i]->interrupt_playback();
 
 // Stop pausing
-	pause_lock.unlock();
+	pause_signal.signal();
 
 // Wait for tracking to finish if it is running
 //printf("PlaybackEngine::interrupt_playback 2\n");
@@ -382,12 +380,15 @@
 
 void PlaybackEngine::run()
 {
-	start_lock.unlock();
+	start_signal.signal();
+	// we don't call que->data_raedy.set_signalhistory(0),
+	// because we accept jobs submitted before running this thread
+	que->accepting.signal(); // now we are accepting
 	do
 	{
 // Wait for current command to finish
 //printf("PlaybackEngine::run 1\n");
-		que->output_lock.lock();
+		que->data_ready.wait_one_signal();
 //printf("PlaybackEngine::run 2\n");
 
 		wait_render_engines();
@@ -395,7 +396,7 @@
 //printf("PlaybackEngine::run 3 %d\n", que->command.command);
 
 // Read the new command
-		que->input_lock.lock();
+		que->accepting.wait_one_signal();
 		if(done) return;
 
 //printf("PlaybackEngine::run 3\n");
@@ -403,7 +404,7 @@
 //printf("PlaybackEngine::run 3 %f %f\n", command->playbackstart, que->command.playbackstart);
 		que->command.reset();
 //printf("PlaybackEngine::run 3 %p\n", this);
-		que->input_lock.unlock();
+		que->accepting.signal(); // we have copied all the data to local structures, so we can already accept new ones
 
 // printf("PlaybackEngine::run 4 %d %x %x\n", 
 // 	this->command->command, 
@@ -420,10 +421,10 @@
 				break;
 
 			case PAUSE:
-				pause_lock.lock();
+				pause_signal.wait_one_signal();
 				init_cursor();
-				pause_lock.lock();
-				pause_lock.unlock();
+				pause_signal.wait_one_signal();
+				pause_signal.signal();
 				stop_cursor();
 				break;
 
Only in hvirtual-1.1.6/cinelerra: playbackengine.C.gcov
diff -u base/cinelerra/playbackengine.h hvirtual-1.1.6/cinelerra/playbackengine.h
--- base/cinelerra/playbackengine.h	2003-07-23 20:43:31.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/playbackengine.h	2003-07-23 22:19:51.000000000 +0200
@@ -10,6 +10,7 @@
 #include "mwindow.inc"
 #include "maxchannels.h"
 #include "mutex.h"
+#include "condvar.h"
 #include "tracking.inc"
 #include "preferences.inc"
 #include "renderengine.inc"
@@ -86,7 +87,7 @@
 // Render engine set
 	ArrayList<RenderEngine*> render_engines;
 // Pause the main loop for the PAUSE command
-	Mutex pause_lock;
+	CondVar pause_signal;
 
 
 
@@ -120,7 +121,8 @@
 	int render_audio();
 	int reset_buttons();
 	int cleanup();
-	Mutex complete, startup_lock, start_lock;
+	Mutex complete, startup_lock;
+	CondVar start_signal;
 
 // ============================ cursor
 	int lock_playback_cursor();
diff -u base/cinelerra/plugindialog.C hvirtual-1.1.6/cinelerra/plugindialog.C
--- base/cinelerra/plugindialog.C	2003-07-23 20:43:54.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/plugindialog.C	2003-07-23 22:19:48.000000000 +0200
@@ -21,6 +21,7 @@
 	window = 0;
 	plugin = 0;
 	Thread::set_synchronous(0);
+	completion.set_signalhistory(3);
 }
 
 PluginDialogThread::~PluginDialogThread()
@@ -28,8 +29,10 @@
 	if(window)
 	{
 		window->set_done(1);
-		completion.lock();
-		completion.unlock();
+//		completion.lock();
+//		completion.unlock();
+		completion.wait_one_signal();
+		// why would we unlock here, except for cleanliness?
 	}
 }
 
@@ -63,7 +66,8 @@
 		}
 
 		strcpy(this->window_title, title);
-		completion.lock();
+//		completion.lock();
+		completion.wait_one_signal();
 		Thread::start();
 	}
 }
@@ -83,7 +87,8 @@
 	result = window->run_window();
 	delete window;
 	window = 0;
-	completion.unlock();
+//	completion.unlock();
+	completion.signal();
 
 // Done at closing
 	if(!result)
diff -u base/cinelerra/plugindialog.h hvirtual-1.1.6/cinelerra/plugindialog.h
--- base/cinelerra/plugindialog.h	2003-07-23 20:43:55.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/plugindialog.h	2003-07-23 22:19:51.000000000 +0200
@@ -19,6 +19,7 @@
 #include "mwindow.inc"
 #include "sharedlocation.h"
 #include "thread.h"
+#include "condvar.h"
 #include "transition.inc"
 
 class PluginDialogThread : public Thread
@@ -43,7 +44,7 @@
 	PluginDialog *window;
 // Plugin being modified if there is one
 	Plugin *plugin;
-	Mutex completion;
+	CondVar completion;
 	char window_title[BCTEXTLEN];
 
 
diff -u base/cinelerra/renderengine.C hvirtual-1.1.6/cinelerra/renderengine.C
--- base/cinelerra/renderengine.C	2003-07-23 20:45:00.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/renderengine.C	2003-07-23 22:19:48.000000000 +0200
@@ -15,7 +15,7 @@
 #include "videodevice.h"
 #include "vrender.h"
 #include "workarounds.h"
-
+#include "condvar.h"
 
 
 RenderEngine::RenderEngine(PlaybackEngine *playback_engine,
@@ -56,6 +56,9 @@
 		mwindow = playback_engine->mwindow;
 	else
 		mwindow = 0;
+
+// if 'signal waiting' bit is set it means new job can be accepted
+	input_signal.signal(); 
 }
 
 RenderEngine::~RenderEngine()
@@ -82,8 +85,9 @@
 // Since the renderengine is often deleted after the input_lock command it must
 // be locked here as well as in the calling routine.
 
-
-	input_lock.lock();
+// waits for previous job to be finished
+// at the beginning previous job gets the finished status in constructor..
+	input_signal.wait_first_signal();
 
 
 //printf("RenderEngine::arm_command 1\n");
@@ -414,11 +418,10 @@
 //printf("RenderEngine::start_command 1 %d\n", command->realtime);
 	if(command->realtime)
 	{
-		interrupt_lock.lock();
-		start_lock.lock();
+		start_signal.set_signalhistory(0); // this is not called only once so we have to cleanup
 		Thread::start();
-		start_lock.lock();
-		start_lock.unlock();
+		start_signal.wait_first_signal();
+
 //printf("RenderEngine::start_command 2 %p %d\n", this, Thread::get_tid());
 	}
 	return 0;
@@ -479,14 +482,14 @@
 
 int RenderEngine::wait_for_completion()
 {
-	input_lock.lock();
-	input_lock.unlock();
+	input_signal.wait_first_signal();
 	return 0;
 }
 
 void RenderEngine::interrupt_playback()
 {
 //printf("RenderEngine::interrupt_playback 0 %p\n", this);
+	start_signal.wait_first_signal(); // waits if thread hasn't been started yet
 	interrupt_lock.lock();
 	interrupted = 1;
 	if(audio)
@@ -566,8 +569,7 @@
 {
 //printf("RenderEngine::run 1 %p\n", this);
 	start_render_threads();
-	start_lock.unlock();
-	interrupt_lock.unlock();
+	start_signal.broadcast();
 
 //printf("RenderEngine::run 2\n");
 	wait_render_threads();
@@ -625,7 +627,7 @@
 	}
 
 //printf("RenderEngine::run 10\n");
-	input_lock.unlock();
+	input_signal.signal();
 //printf("RenderEngine::run 6\n");
 	interrupt_lock.unlock();
 //printf("RenderEngine::run 7 %p\n", this);
diff -u base/cinelerra/renderengine.h hvirtual-1.1.6/cinelerra/renderengine.h
--- base/cinelerra/renderengine.h	2003-07-23 20:45:00.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/renderengine.h	2003-07-23 22:19:51.000000000 +0200
@@ -17,6 +17,7 @@
 #include "transportque.inc"
 #include "videodevice.inc"
 #include "vrender.inc"
+#include "condvar.h"
 
 class RenderEngine : public Thread
 {
@@ -87,10 +88,9 @@
 // Canvas if being used for CWindow
 	Canvas *output;
 // Lock out new commands until completion
-	Mutex input_lock;
+	CondVar input_signal;
 // Lock out interrupts until started
-	Mutex start_lock;
-	Mutex output_lock;
+	CondVar start_signal;
 	int done;
 	AudioDevice *audio;
 	VideoDevice *video;
diff -u base/cinelerra/tracking.C hvirtual-1.1.6/cinelerra/tracking.C
--- base/cinelerra/tracking.C	2003-07-23 20:46:11.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/tracking.C	2003-07-23 22:19:48.000000000 +0200
@@ -17,7 +17,7 @@
 #include "renderengine.h"
 #include "mainsession.h"
 #include "trackcanvas.h"
-
+#include "condvar.h"
 
 
 // States
@@ -41,14 +41,13 @@
 Tracking::~Tracking()
 {
 	state = DONE;
-	pause_lock.unlock();
+	pause_signal.signal();
 	Thread::join();
 }
 
 void Tracking::create_objects()
 {
-	startup_lock.lock();
-	pause_lock.lock();
+//	pause_lock.lock();
 	start();
 }
 
@@ -57,7 +56,8 @@
 	last_position = new_position;
 	state = PLAYING;
 	draw();
-	pause_lock.unlock();
+//	pause_lock.unlock();
+	pause_signal.signal();
 	return 0;
 }
 
@@ -66,7 +66,8 @@
 // Wait to change state
 	loop_lock.lock();
 // Stop loop
-	pause_lock.lock();
+//	pause_lock.lock();
+	pause_signal.wait_one_signal();
 	state = PAUSED;
 	loop_lock.unlock();
 
@@ -175,8 +176,7 @@
 
 int Tracking::wait_for_startup()
 {
-	startup_lock.lock();
-	startup_lock.unlock();
+	startup_signal.wait_first_signal();
 	return 0;
 }
 
@@ -191,14 +191,15 @@
 	int i, j, pass;
 	int audio_on = 0;
 
-	startup_lock.unlock();
+	startup_signal.broadcast();
 
 //printf("Tracking::run 1\n");
 	while(state != DONE)
 	{
-		pause_lock.lock();
-		pause_lock.unlock();
-
+//		pause_lock.lock();
+//		pause_lock.unlock();
+		pause_signal.wait_one_signal();
+		pause_signal.signal();
 //printf("Tracking::run 2\n");
 		loop_lock.lock();
 		if(state != PAUSED && state != DONE)
diff -u base/cinelerra/tracking.h hvirtual-1.1.6/cinelerra/tracking.h
--- base/cinelerra/tracking.h	2003-07-23 20:46:11.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/tracking.h	2003-07-23 22:19:51.000000000 +0200
@@ -8,6 +8,7 @@
 #include "mwindow.inc"
 #include "mwindowgui.inc"
 #include "mutex.h"
+#include "condvar.h"
 #include "playbackengine.inc"
 #include "thread.h"
 #include "timer.h"
@@ -58,13 +59,13 @@
 	int wait_for_startup();
 	int view_follows_playback;
 // Stop cursor loop when not playing
-	Mutex pause_lock;
+	CondVar pause_signal;
 // Exclude changes in state during the main loop
 	Mutex loop_lock;
 // Exclude accesses to the cursor
 	Mutex cursor_lock;
 // Delay until startup
-	Mutex startup_lock;
+	CondVar startup_signal;
 	MWindow *mwindow;
 	MWindowGUI *gui;
 	double last_position;
diff -u base/cinelerra/transportque.C hvirtual-1.1.6/cinelerra/transportque.C
--- base/cinelerra/transportque.C	2003-07-23 20:46:22.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/transportque.C	2003-07-23 22:19:48.000000000 +0200
@@ -196,7 +196,6 @@
 
 TransportQue::TransportQue()
 {
-	output_lock.lock();
 }
 
 TransportQue::~TransportQue()
@@ -210,7 +209,7 @@
 		int resume)
 {
 //printf("TransportQue::send_command 1\n");
-	input_lock.lock();
+	accepting.wait_one_signal();
 	this->command.command = command;
 // Mutually exclusive operation
 	this->command.change_type |= change_type;
@@ -245,15 +244,15 @@
 
 //printf("TransportQue::send_command 3\n");
 //printf("TransportQue::send_command 2 %p %d %d\n", new_edl, this->command.playbackstart);
-	input_lock.unlock();
-	output_lock.unlock();
+	accepting.signal();
+	data_ready.signal();
 //printf("TransportQue::send_command 4\n");
 	return 0;
 }
 
 void TransportQue::update_change_type(int change_type)
 {
-	input_lock.lock();
+	accepting.wait_one_signal(); // this is like input lock
 	this->command.change_type |= change_type;
-	input_lock.unlock();
+	accepting.signal();
 }
diff -u base/cinelerra/transportque.h hvirtual-1.1.6/cinelerra/transportque.h
--- base/cinelerra/transportque.h	2003-07-23 20:46:23.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/transportque.h	2003-07-23 22:19:51.000000000 +0200
@@ -4,9 +4,11 @@
 #include "canvas.inc"
 #include "edl.inc"
 #include "mutex.h"
+#include "condvar.h"
 #include "preferences.inc"
 #include "transportque.inc"
 
+
 class TransportCommand
 {
 public:
@@ -58,7 +60,7 @@
 	void update_change_type(int change_type);
 
 	TransportCommand command;
-	Mutex input_lock, output_lock;
+	CondVar data_ready, accepting;
 };
 
 #endif
diff -u base/cinelerra/vrender.C hvirtual-1.1.6/cinelerra/vrender.C
--- base/cinelerra/vrender.C	2003-07-23 20:47:28.000000000 +0200
+++ hvirtual-1.1.6/cinelerra/vrender.C	2003-07-23 22:19:48.000000000 +0200
@@ -285,7 +285,7 @@
 	framerate_counter = 0;
 	framerate_timer.update();
 
-	start_lock.unlock();
+	start_signal.signal();
 
 
 //printf("VRender:run 2 %d %d %d\n", done, renderengine->video->interrupt, last_playback);
